diff options
author | Paul Mackerras <paulus@samba.org> | 2007-05-10 07:08:37 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-05-10 07:08:37 -0400 |
commit | 2ecf042ef530dd0943e41d84b6344f507941af3e (patch) | |
tree | 73100361dd74e3f80f14c7c81ba4675948983f44 /arch | |
parent | 32a56ebb24f23da1bbaf24292acf85b6c04526ab (diff) | |
parent | de5603748af8bf7deac403e6ba92887f8d18e812 (diff) |
Merge branch 'linux-2.6'
Diffstat (limited to 'arch')
172 files changed, 3762 insertions, 923 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 | |||
354 | config ARCH_S3C2410 | 354 | config 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. |
50 | arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7a,-march=armv5t -Wa$(comma)-march=armv7a) | ||
50 | arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) | 51 | arch-$(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 | ||
54 | ifeq ($(CONFIG_CPU_32v6),y) | ||
51 | arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) | 55 | arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) |
56 | endif | ||
52 | arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) | 57 | arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) |
53 | arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t | 58 | arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t |
54 | arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 | 59 | arch-$(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 |
38 | ENTRY(stext) | 38 | ENTRY(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 |
78 | ENTRY(stext) | 78 | ENTRY(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 | */ |
33 | union thread_union init_thread_union | 33 | union 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 |
489 | asmlinkage void do_local_timer(struct pt_regs *regs) | 489 | asmlinkage 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 | */ |
554 | asmlinkage void do_IPI(struct pt_regs *regs) | 554 | asmlinkage 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-at91/Kconfig b/arch/arm/mach-at91/Kconfig index e238ad8cfd8f..018d637f87fc 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -107,7 +107,7 @@ config ARCH_AT91SAM9260_SAM9XE | |||
107 | depends on ARCH_AT91SAM9260 | 107 | depends on ARCH_AT91SAM9260 |
108 | help | 108 | help |
109 | Select this if you are using Atmel's AT91SAM9XE System-on-Chip. | 109 | Select this if you are using Atmel's AT91SAM9XE System-on-Chip. |
110 | They are basicaly AT91SAM9260s with various sizes of embedded Flash. | 110 | They are basically AT91SAM9260s with various sizes of embedded Flash. |
111 | 111 | ||
112 | comment "AT91SAM9260 / AT91SAM9XE Board Type" | 112 | comment "AT91SAM9260 / AT91SAM9XE Board Type" |
113 | 113 | ||
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 8781aaeb576b..856c681ebbbc 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig | |||
@@ -22,6 +22,7 @@ comment "OMAP Board Type" | |||
22 | config MACH_OMAP_INNOVATOR | 22 | config 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 | |||
29 | config MACH_OMAP_H2 | 30 | config 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 | |||
36 | config MACH_OMAP_H3 | 38 | config 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 | |||
43 | config MACH_OMAP_OSK | 46 | config 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. |
@@ -84,7 +87,7 @@ config MACH_OMAP_PALMTE | |||
84 | Support for the Palm Tungsten E PDA. Currently only the LCD panel | 87 | Support for the Palm Tungsten E PDA. Currently only the LCD panel |
85 | is supported. To boot the kernel, you'll need a PalmOS compatible | 88 | is supported. To boot the kernel, you'll need a PalmOS compatible |
86 | bootloader; check out http://palmtelinux.sourceforge.net for more | 89 | bootloader; check out http://palmtelinux.sourceforge.net for more |
87 | informations. | 90 | information. |
88 | Say Y here if you have such a PDA, say NO otherwise. | 91 | Say Y here if you have such a PDA, say NO otherwise. |
89 | 92 | ||
90 | config MACH_NOKIA770 | 93 | config MACH_NOKIA770 |
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 | |||
37 | led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o | 37 | led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o |
38 | led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o | 38 | led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o |
39 | obj-$(CONFIG_LEDS) += $(led-y) | 39 | obj-$(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 | ||
249 | void omap_fsample_init_irq(void) | 249 | static 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 | ||
458 | void h3_init_irq(void) | 458 | static 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 | ||
311 | void innovator_init_irq(void) | 311 | static 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 | ||
249 | void omap_perseus2_init_irq(void) | 249 | static 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 | |||
29 | static u64 irda_dmamask = 0xffffffff; | ||
30 | |||
31 | static struct platform_device omap1610ir_device = { | ||
32 | .name = "omap1610-ir", | ||
33 | .id = -1, | ||
34 | .dev = { | ||
35 | .dma_mask = &irda_dmamask, | ||
36 | }, | ||
37 | }; | ||
38 | |||
39 | static 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 | ||
53 | static 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) | |||
90 | static inline void omap_init_rtc(void) {} | 61 | static 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 | |||
76 | static 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 | |||
88 | static struct platform_device mbox_device = { | ||
89 | .name = "mailbox", | ||
90 | .id = -1, | ||
91 | .num_resources = ARRAY_SIZE(mbox_resources), | ||
92 | .resource = mbox_resources, | ||
93 | }; | ||
94 | |||
95 | static inline void omap_init_mbox(void) | ||
96 | { | ||
97 | platform_device_register(&mbox_device); | ||
98 | } | ||
99 | #else | ||
100 | static 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 | ||
22 | extern int omap1_clk_init(void); | 21 | extern int omap1_clk_init(void); |
23 | extern void omap_check_revision(void); | 22 | extern void omap_check_revision(void); |
24 | extern void omap_sram_init(void); | 23 | extern void omap_sram_init(void); |
24 | extern 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 | |||
30 | unsigned long mbox_base; | ||
31 | |||
32 | struct omap_mbox1_fifo { | ||
33 | unsigned long cmd; | ||
34 | unsigned long data; | ||
35 | unsigned long flag; | ||
36 | }; | ||
37 | |||
38 | struct omap_mbox1_priv { | ||
39 | struct omap_mbox1_fifo tx_fifo; | ||
40 | struct omap_mbox1_fifo rx_fifo; | ||
41 | }; | ||
42 | |||
43 | static inline int mbox_read_reg(unsigned int reg) | ||
44 | { | ||
45 | return __raw_readw(mbox_base + reg); | ||
46 | } | ||
47 | |||
48 | static inline void mbox_write_reg(unsigned int val, unsigned int reg) | ||
49 | { | ||
50 | __raw_writew(val, mbox_base + reg); | ||
51 | } | ||
52 | |||
53 | /* msg */ | ||
54 | static 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 | |||
66 | static inline void | ||
67 | omap1_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 | |||
76 | static inline int omap1_mbox_fifo_empty(struct omap_mbox *mbox) | ||
77 | { | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static 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 */ | ||
90 | static inline void | ||
91 | omap1_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 | |||
97 | static inline void | ||
98 | omap1_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 | |||
104 | static inline int | ||
105 | omap1_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 | |||
112 | static 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 */ | ||
126 | static 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 | |||
139 | struct omap_mbox mbox_dsp_info = { | ||
140 | .name = "dsp", | ||
141 | .ops = &omap1_mbox_ops, | ||
142 | .priv = &omap1_mbox_dsp_priv, | ||
143 | }; | ||
144 | EXPORT_SYMBOL(mbox_dsp_info); | ||
145 | |||
146 | static 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 | |||
178 | static int omap1_mbox_remove(struct platform_device *pdev) | ||
179 | { | ||
180 | omap_mbox_unregister(&mbox_dsp_info); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static struct platform_driver omap1_mbox_driver = { | ||
186 | .probe = omap1_mbox_probe, | ||
187 | .remove = omap1_mbox_remove, | ||
188 | .driver = { | ||
189 | .name = "mailbox", | ||
190 | }, | ||
191 | }; | ||
192 | |||
193 | static int __init omap1_mbox_init(void) | ||
194 | { | ||
195 | return platform_driver_register(&omap1_mbox_driver); | ||
196 | } | ||
197 | |||
198 | static void __exit omap1_mbox_exit(void) | ||
199 | { | ||
200 | platform_driver_unregister(&omap1_mbox_driver); | ||
201 | } | ||
202 | |||
203 | module_init(omap1_mbox_init); | ||
204 | module_exit(omap1_mbox_exit); | ||
205 | |||
206 | MODULE_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 | ||
13 | comment "OMAP Board Type" | 14 | comment "OMAP Board Type" |
14 | depends on ARCH_OMAP2 | 15 | depends on ARCH_OMAP2 |
@@ -20,6 +21,7 @@ config MACH_OMAP_GENERIC | |||
20 | config MACH_OMAP_H4 | 21 | config 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 | ||
24 | config MACH_OMAP_APOLLON | 26 | config 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 | ||
269 | static struct resource h4_led_resources[] = { | ||
270 | [0] = { | ||
271 | .flags = IORESOURCE_MEM, | ||
272 | }, | ||
273 | }; | ||
274 | |||
275 | static 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 | |||
269 | static struct platform_device *h4_devices[] __initdata = { | 282 | static 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 | ||
277 | static inline void __init h4_init_smc91x(void) | 291 | static 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 | ||
44 | static struct platform_device omap_i2c_device2 = { | 44 | static 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 | |||
72 | static 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 | |||
88 | static struct platform_device mbox_device = { | ||
89 | .name = "mailbox", | ||
90 | .id = -1, | ||
91 | .num_resources = ARRAY_SIZE(mbox_resources), | ||
92 | .resource = mbox_resources, | ||
93 | }; | ||
94 | |||
95 | static inline void omap_init_mbox(void) | ||
96 | { | ||
97 | platform_device_register(&mbox_device); | ||
98 | } | ||
99 | #else | ||
100 | static 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 | |||
116 | static struct omap2_mcspi_platform_config omap2_mcspi1_config = { | 148 | static 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 | ||
152 | static struct resource omap2_mcspi1_resources[] = { | ||
153 | { | ||
154 | .start = OMAP2_MCSPI1_BASE, | ||
155 | .end = OMAP2_MCSPI1_BASE + 0xff, | ||
156 | .flags = IORESOURCE_MEM, | ||
157 | }, | ||
158 | }; | ||
159 | |||
121 | struct platform_device omap2_mcspi1 = { | 160 | struct 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 | ||
129 | static struct omap2_mcspi_platform_config omap2_mcspi2_config = { | 170 | static 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 | ||
174 | static struct resource omap2_mcspi2_resources[] = { | ||
175 | { | ||
176 | .start = OMAP2_MCSPI2_BASE, | ||
177 | .end = OMAP2_MCSPI2_BASE + 0xff, | ||
178 | .flags = IORESOURCE_MEM, | ||
179 | }, | ||
180 | }; | ||
181 | |||
134 | struct platform_device omap2_mcspi2 = { | 182 | struct 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 | } |
165 | arch_initcall(omap2_init_devices); | 216 | arch_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 | ||
249 | static void gpmc_cs_set_reserved(int cs, int reserved) | 249 | int 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 | ||
255 | static int gpmc_cs_reserved(int cs) | 260 | int 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); | |||
27 | extern int omap2_clk_init(void); | 27 | extern int omap2_clk_init(void); |
28 | extern void omap2_check_revision(void); | 28 | extern void omap2_check_revision(void); |
29 | extern void gpmc_init(void); | 29 | extern void gpmc_init(void); |
30 | extern 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 | ||
66 | void __init omap2_init_common_hw(void) | 79 | void __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 | |||
51 | static 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 | |||
56 | struct omap_mbox2_fifo { | ||
57 | unsigned long msg; | ||
58 | unsigned long fifo_stat; | ||
59 | unsigned long msg_stat; | ||
60 | }; | ||
61 | |||
62 | struct 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 | |||
71 | static struct clk *mbox_ick_handle; | ||
72 | |||
73 | static inline unsigned int mbox_read_reg(unsigned int reg) | ||
74 | { | ||
75 | return __raw_readl(mbox_base + reg); | ||
76 | } | ||
77 | |||
78 | static 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 */ | ||
84 | static 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 | |||
103 | static 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 */ | ||
110 | static 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 | |||
117 | static 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 | |||
124 | static 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 | |||
131 | static 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 */ | ||
139 | static 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 | |||
150 | static 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 | |||
161 | static 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 | |||
170 | static 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 | |||
181 | static 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 */ | ||
205 | static 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 | |||
220 | struct omap_mbox mbox_dsp_info = { | ||
221 | .name = "dsp", | ||
222 | .ops = &omap2_mbox_ops, | ||
223 | .priv = &omap2_mbox_dsp_priv, | ||
224 | }; | ||
225 | EXPORT_SYMBOL(mbox_dsp_info); | ||
226 | |||
227 | /* IVA */ | ||
228 | static 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 | |||
243 | static struct omap_mbox mbox_iva_info = { | ||
244 | .name = "iva", | ||
245 | .ops = &omap2_mbox_ops, | ||
246 | .priv = &omap2_mbox_iva_priv, | ||
247 | }; | ||
248 | |||
249 | static 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 | |||
291 | static int omap2_mbox_remove(struct platform_device *pdev) | ||
292 | { | ||
293 | omap_mbox_unregister(&mbox_dsp_info); | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static struct platform_driver omap2_mbox_driver = { | ||
298 | .probe = omap2_mbox_probe, | ||
299 | .remove = omap2_mbox_remove, | ||
300 | .driver = { | ||
301 | .name = "mailbox", | ||
302 | }, | ||
303 | }; | ||
304 | |||
305 | static int __init omap2_mbox_init(void) | ||
306 | { | ||
307 | return platform_driver_register(&omap2_mbox_driver); | ||
308 | } | ||
309 | |||
310 | static void __exit omap2_mbox_exit(void) | ||
311 | { | ||
312 | platform_driver_unregister(&omap2_mbox_driver); | ||
313 | } | ||
314 | |||
315 | module_init(omap2_mbox_init); | ||
316 | module_exit(omap2_mbox_exit); | ||
317 | |||
318 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index 637aaba65390..d1eeed2ad47c 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S | 1 | /* linux/arch/arm/mach-s3c2410/sleep.S |
2 | * | 2 | * |
3 | * Copyright (c) 2004 Simtec Electronics | 3 | * Copyright (c) 2004 Simtec Electronics |
4 | * Ben Dooks <ben@simtec.co.uk> | 4 | * Ben Dooks <ben@simtec.co.uk> |
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 | ||
370 | config 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. |
371 | config CPU_32v3 | 384 | config CPU_32v3 |
@@ -391,6 +404,9 @@ config CPU_32v5 | |||
391 | config CPU_32v6 | 404 | config CPU_32v6 |
392 | bool | 405 | bool |
393 | 406 | ||
407 | config CPU_32v7 | ||
408 | bool | ||
409 | |||
394 | # The abort model | 410 | # The abort model |
395 | config CPU_ABRT_NOMMU | 411 | config CPU_ABRT_NOMMU |
396 | bool | 412 | bool |
@@ -413,6 +429,9 @@ config CPU_ABRT_EV5TJ | |||
413 | config CPU_ABRT_EV6 | 429 | config CPU_ABRT_EV6 |
414 | bool | 430 | bool |
415 | 431 | ||
432 | config CPU_ABRT_EV7 | ||
433 | bool | ||
434 | |||
416 | # The cache model | 435 | # The cache model |
417 | config CPU_CACHE_V3 | 436 | config CPU_CACHE_V3 |
418 | bool | 437 | bool |
@@ -429,6 +448,9 @@ config CPU_CACHE_V4WB | |||
429 | config CPU_CACHE_V6 | 448 | config CPU_CACHE_V6 |
430 | bool | 449 | bool |
431 | 450 | ||
451 | config CPU_CACHE_V7 | ||
452 | bool | ||
453 | |||
432 | config CPU_CACHE_VIVT | 454 | config CPU_CACHE_VIVT |
433 | bool | 455 | bool |
434 | 456 | ||
@@ -503,7 +525,7 @@ comment "Processor Features" | |||
503 | 525 | ||
504 | config ARM_THUMB | 526 | config 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 | ||
603 | config 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 | |||
581 | config CPU_BPREDICT_DISABLE | 609 | config 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 | |||
24 | obj-$(CONFIG_CPU_ABRT_EV5T) += abort-ev5t.o | 24 | obj-$(CONFIG_CPU_ABRT_EV5T) += abort-ev5t.o |
25 | obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o | 25 | obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o |
26 | obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o | 26 | obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o |
27 | obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o | ||
27 | 28 | ||
28 | obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o | 29 | obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o |
29 | obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o | 30 | obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o |
30 | obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o | 31 | obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o |
31 | obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o | 32 | obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o |
32 | obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o | 33 | obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o |
34 | obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o | ||
33 | 35 | ||
34 | obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o | 36 | obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o |
35 | obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o | 37 | obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o |
@@ -66,5 +68,6 @@ obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o | |||
66 | obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o | 68 | obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o |
67 | obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o | 69 | obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o |
68 | obj-$(CONFIG_CPU_V6) += proc-v6.o | 70 | obj-$(CONFIG_CPU_V6) += proc-v6.o |
71 | obj-$(CONFIG_CPU_V7) += proc-v7.o | ||
69 | 72 | ||
70 | obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o | 73 | obj-$(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 | ||
18 | ENTRY(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 | */ | ||
28 | ENTRY(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 | ||
34 | loop1: | ||
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 | ||
50 | loop2: | ||
51 | mov r9, r4 @ create working copy of max way size | ||
52 | loop3: | ||
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 | ||
60 | skip: | ||
61 | add r10, r10, #2 @ increment cache number | ||
62 | cmp r3, r10 | ||
63 | bgt loop1 | ||
64 | finished: | ||
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 | */ | ||
81 | ENTRY(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 | */ | ||
96 | ENTRY(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 | */ | ||
111 | ENTRY(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 | */ | ||
127 | ENTRY(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 | */ | ||
143 | ENTRY(v7_coherent_user_range) | ||
144 | dcache_line_size r2, r3 | ||
145 | sub r3, r2, #1 | ||
146 | bic r0, r0, r3 | ||
147 | 1: 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 | */ | ||
167 | ENTRY(v7_flush_kern_dcache_page) | ||
168 | dcache_line_size r2, r3 | ||
169 | add r1, r0, #PAGE_SZ | ||
170 | 1: | ||
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 | */ | ||
188 | ENTRY(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 | ||
198 | 1: | ||
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 | */ | ||
211 | ENTRY(v7_dma_clean_range) | ||
212 | dcache_line_size r2, r3 | ||
213 | sub r3, r2, #1 | ||
214 | bic r0, r0, r3 | ||
215 | 1: | ||
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 | */ | ||
228 | ENTRY(v7_dma_flush_range) | ||
229 | dcache_line_size r2, r3 | ||
230 | sub r3, r2, #1 | ||
231 | bic r0, r0, r3 | ||
232 | 1: | ||
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 | ||
243 | ENTRY(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 | ||
17 | unsigned int cpu_last_asid = { 1 << ASID_BITS }; | 17 | static DEFINE_SPINLOCK(cpu_asid_lock); |
18 | unsigned 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 | |||
26 | ENTRY(cpu_v7_proc_init) | ||
27 | mov pc, lr | ||
28 | |||
29 | ENTRY(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 | ||
44 | ENTRY(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 | */ | ||
54 | ENTRY(cpu_v7_do_idle) | ||
55 | .long 0xe320f003 @ ARM V7 WFI instruction | ||
56 | mov pc, lr | ||
57 | |||
58 | ENTRY(cpu_v7_dcache_clean_area) | ||
59 | #ifndef TLB_CAN_READ_FROM_L1_CACHE | ||
60 | dcache_line_size r2, r3 | ||
61 | 1: 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 | */ | ||
79 | ENTRY(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 | ||
85 | 1: 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 | */ | ||
111 | ENTRY(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 | |||
141 | cpu_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 | ||
204 | cr1_clear: | ||
205 | .word 0x0120c302 | ||
206 | cr1_set: | ||
207 | .word 0x00c0387d | ||
208 | |||
209 | __v7_setup_stack: | ||
210 | .space 4 * 11 @ 11 registers | ||
211 | |||
212 | .type v7_processor_functions, #object | ||
213 | ENTRY(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 | ||
225 | cpu_arch_name: | ||
226 | .asciz "armv7" | ||
227 | .size cpu_arch_name, . - cpu_arch_name | ||
228 | |||
229 | .type cpu_elf_name, #object | ||
230 | cpu_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 | ||
21 | comment "OMAP Feature Selections" | 21 | comment "OMAP Feature Selections" |
22 | 22 | ||
23 | config OMAP_DEBUG_LEDS | ||
24 | bool | ||
25 | help | ||
26 | For debug card leds on TI reference boards. | ||
27 | |||
23 | config OMAP_RESET_CLOCKS | 28 | config 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 | ||
66 | config 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 | |||
61 | choice | 74 | choice |
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 |
6 | obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o fb.o | 6 | obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o \ |
7 | usb.o fb.o | ||
7 | obj-m := | 8 | obj-m := |
8 | obj-n := | 9 | obj-n := |
9 | obj- := | 10 | obj- := |
@@ -16,4 +17,4 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o | |||
16 | 17 | ||
17 | obj-$(CONFIG_CPU_FREQ) += cpu-omap.o | 18 | obj-$(CONFIG_CPU_FREQ) += cpu-omap.o |
18 | obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o | 19 | obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o |
19 | 20 | obj-$(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 | ||
34 | static struct clk_functions *arch_clock; | 34 | static struct clk_functions *arch_clock; |
35 | 35 | ||
36 | #ifdef CONFIG_PM_DEBUG | ||
37 | |||
38 | static 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 | |||
54 | void 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 | |||
37 | static spinlock_t lock; | ||
38 | static struct h2p2_dbg_fpga __iomem *fpga; | ||
39 | static 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 | |||
66 | static 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 | |||
180 | done: | ||
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 | |||
191 | struct dbg_led { | ||
192 | struct led_classdev cdev; | ||
193 | u16 mask; | ||
194 | }; | ||
195 | |||
196 | static 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 | |||
226 | static void | ||
227 | fpga_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 | |||
241 | static 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 | |||
259 | static 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 | |||
284 | static int fpga_suspend_late(struct platform_device *pdev, pm_message_t mesg) | ||
285 | { | ||
286 | __raw_writew(~0, &fpga->leds); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int fpga_resume_early(struct platform_device *pdev) | ||
291 | { | ||
292 | __raw_writew(~hw_led_state, &fpga->leds); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | |||
297 | static 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 | |||
304 | static 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 | } | ||
314 | fs_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 | |||
32 | static struct dsp_platform_data dsp_pdata = { | ||
33 | .kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list), | ||
34 | }; | ||
35 | |||
36 | static struct resource omap_dsp_resources[] = { | ||
37 | { | ||
38 | .name = "dsp_mmu", | ||
39 | .start = -1, | ||
40 | .flags = IORESOURCE_IRQ, | ||
41 | }, | ||
42 | }; | ||
43 | |||
44 | static 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 | |||
54 | static 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 | |||
73 | int 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 | } | ||
85 | EXPORT_SYMBOL(dsp_kfunc_device_register); | ||
86 | |||
87 | #else | ||
88 | static 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 | ||
50 | static struct platform_device omap_i2c_device1 = { | 114 | static 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 | } |
448 | arch_initcall(omap_init_devices); | 513 | arch_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 | ||
18 | static struct omapfb_platform_data omapfb_config; | 41 | static struct omapfb_platform_data omapfb_config; |
42 | static int config_invalid; | ||
43 | static int configured_regions; | ||
19 | 44 | ||
20 | static u64 omap_fb_dma_mask = ~(u32)0; | 45 | static 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 */ | 58 | static inline int ranges_overlap(unsigned long start1, unsigned long size1, |
34 | void 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; | 65 | static 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 | 73 | static 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 | */ | ||
93 | static 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 | |||
116 | static 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 | |||
135 | static 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 | */ | ||
174 | void 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 | */ | ||
231 | unsigned 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 | |||
300 | void omapfb_set_ctrl_platform_data(void *data) | ||
301 | { | ||
302 | omapfb_config.ctrl_platform_data = data; | ||
56 | } | 303 | } |
57 | 304 | ||
58 | static inline int omap_init_fb(void) | 305 | static 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 | ||
75 | void omapfb_reserve_mem(void) {} | 331 | void omapfb_reserve_sdram(void) {} |
332 | unsigned 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 | */ |
1548 | int omap_gpio_init(void) | 1547 | int __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 | |||
37 | static struct omap_mbox *mboxes; | ||
38 | static DEFINE_RWLOCK(mboxes_lock); | ||
39 | |||
40 | /* Mailbox Sequence Bit function */ | ||
41 | void omap_mbox_init_seq(struct omap_mbox *mbox) | ||
42 | { | ||
43 | mbox_seq_init(mbox); | ||
44 | } | ||
45 | EXPORT_SYMBOL(omap_mbox_init_seq); | ||
46 | |||
47 | /* | ||
48 | * message sender | ||
49 | */ | ||
50 | static 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 | |||
74 | int 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 | } | ||
93 | EXPORT_SYMBOL(omap_mbox_msg_send); | ||
94 | |||
95 | static 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 | */ | ||
128 | static 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 | */ | ||
164 | static void mbox_txq_fn(request_queue_t * q) | ||
165 | { | ||
166 | } | ||
167 | |||
168 | static void mbox_rxq_fn(request_queue_t * q) | ||
169 | { | ||
170 | } | ||
171 | |||
172 | static 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 | |||
179 | static 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 | |||
213 | static 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 | */ | ||
229 | static ssize_t | ||
230 | omap_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 | |||
247 | static ssize_t | ||
248 | omap_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 | |||
283 | static DEVICE_ATTR(mbox, S_IRUGO | S_IWUSR, omap_mbox_read, omap_mbox_write); | ||
284 | |||
285 | static ssize_t mbox_show(struct class *class, char *buf) | ||
286 | { | ||
287 | return sprintf(buf, "mbox"); | ||
288 | } | ||
289 | |||
290 | static CLASS_ATTR(mbox, S_IRUGO, mbox_show, NULL); | ||
291 | |||
292 | static struct class omap_mbox_class = { | ||
293 | .name = "omap_mbox", | ||
294 | }; | ||
295 | |||
296 | static 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; | ||
318 | error: | ||
319 | kfree(mq); | ||
320 | return NULL; | ||
321 | } | ||
322 | |||
323 | static void mbox_queue_free(struct omap_mbox_queue *q) | ||
324 | { | ||
325 | blk_cleanup_queue(q->queue); | ||
326 | kfree(q); | ||
327 | } | ||
328 | |||
329 | static 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 | |||
395 | static 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 | |||
408 | static 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 | |||
420 | struct 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 | } | ||
440 | EXPORT_SYMBOL(omap_mbox_get); | ||
441 | |||
442 | void omap_mbox_put(struct omap_mbox *mbox) | ||
443 | { | ||
444 | omap_mbox_fini(mbox); | ||
445 | } | ||
446 | EXPORT_SYMBOL(omap_mbox_put); | ||
447 | |||
448 | int 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 | } | ||
468 | EXPORT_SYMBOL(omap_mbox_register); | ||
469 | |||
470 | int 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 | } | ||
489 | EXPORT_SYMBOL(omap_mbox_unregister); | ||
490 | |||
491 | static 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 | |||
500 | static 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 | |||
506 | subsys_initcall(omap_mbox_class_init); | ||
507 | module_exit(omap_mbox_class_exit); | ||
508 | |||
509 | MODULE_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. */ | ||
28 | static 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 | |||
34 | static 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 | |||
42 | static 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 | ||
51 | static inline void mbox_seq_init(struct omap_mbox *mbox) | ||
52 | { | ||
53 | } | ||
54 | static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg) | ||
55 | { | ||
56 | } | ||
57 | static 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 */ | ||
64 | static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) | ||
65 | { | ||
66 | return mbox->ops->fifo_read(mbox); | ||
67 | } | ||
68 | static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) | ||
69 | { | ||
70 | mbox->ops->fifo_write(mbox, msg); | ||
71 | } | ||
72 | static inline int mbox_fifo_empty(struct omap_mbox *mbox) | ||
73 | { | ||
74 | return mbox->ops->fifo_empty(mbox); | ||
75 | } | ||
76 | static inline int mbox_fifo_full(struct omap_mbox *mbox) | ||
77 | { | ||
78 | return mbox->ops->fifo_full(mbox); | ||
79 | } | ||
80 | |||
81 | /* Mailbox IRQ handle functions */ | ||
82 | static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) | ||
83 | { | ||
84 | mbox->ops->enable_irq(mbox, irq); | ||
85 | } | ||
86 | static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) | ||
87 | { | ||
88 | mbox->ops->disable_irq(mbox, irq); | ||
89 | } | ||
90 | static 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 | } | ||
95 | static 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 | ||
49 | static unsigned long omap_sram_start; | ||
49 | static unsigned long omap_sram_base; | 50 | static unsigned long omap_sram_base; |
50 | static unsigned long omap_sram_size; | 51 | static unsigned long omap_sram_size; |
51 | static unsigned long omap_sram_ceil; | 52 | static unsigned long omap_sram_ceil; |
52 | 53 | ||
53 | unsigned long omap_fb_sram_start; | 54 | extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart, |
54 | unsigned 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 | ||
80 | void 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 | */ |
112 | void __init omap_detect_sram(void) | 91 | void __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: |
286 | bad: | ||
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: |
384 | bad: | ||
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; | |||
329 | static struct resource ohci_resources[] = { | 445 | static 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); |
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index 435349dc3243..7b7ae790b00d 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S | |||
@@ -1,4 +1,4 @@ | |||
1 | /* linux/arch/arm/mach-s3c2410/sleep.S | 1 | /* linux/arch/arm/plat-s3c24xx/sleep.S |
2 | * | 2 | * |
3 | * Copyright (c) 2004 Simtec Electronics | 3 | * Copyright (c) 2004 Simtec Electronics |
4 | * Ben Dooks <ben@simtec.co.uk> | 4 | * Ben Dooks <ben@simtec.co.uk> |
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile index 6115fc1f0cfa..dc6bc01f232c 100644 --- a/arch/avr32/Makefile +++ b/arch/avr32/Makefile | |||
@@ -16,7 +16,7 @@ AFLAGS += -mrelax -mno-pic | |||
16 | CFLAGS_MODULE += -mno-relax | 16 | CFLAGS_MODULE += -mno-relax |
17 | LDFLAGS_vmlinux += --relax | 17 | LDFLAGS_vmlinux += --relax |
18 | 18 | ||
19 | cpuflags-$(CONFIG_CPU_AP7000) += -mcpu=ap7000 | 19 | cpuflags-$(CONFIG_CPU_AT32AP7000) += -mcpu=ap7000 |
20 | 20 | ||
21 | CFLAGS += $(cpuflags-y) | 21 | CFLAGS += $(cpuflags-y) |
22 | AFLAGS += $(cpuflags-y) | 22 | AFLAGS += $(cpuflags-y) |
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 4e4181ed1c6d..13f988402613 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c | |||
@@ -330,13 +330,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
330 | { | 330 | { |
331 | struct pt_regs *childregs; | 331 | struct pt_regs *childregs; |
332 | 332 | ||
333 | childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)p->thread_info)) - 1; | 333 | childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)task_stack_page(p))) - 1; |
334 | *childregs = *regs; | 334 | *childregs = *regs; |
335 | 335 | ||
336 | if (user_mode(regs)) | 336 | if (user_mode(regs)) |
337 | childregs->sp = usp; | 337 | childregs->sp = usp; |
338 | else | 338 | else |
339 | childregs->sp = (unsigned long)p->thread_info + THREAD_SIZE; | 339 | childregs->sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; |
340 | 340 | ||
341 | childregs->r12 = 0; /* Set return value for child */ | 341 | childregs->r12 = 0; /* Set return value for child */ |
342 | 342 | ||
@@ -403,7 +403,7 @@ unsigned long get_wchan(struct task_struct *p) | |||
403 | if (!p || p == current || p->state == TASK_RUNNING) | 403 | if (!p || p == current || p->state == TASK_RUNNING) |
404 | return 0; | 404 | return 0; |
405 | 405 | ||
406 | stack_page = (unsigned long)p->thread_info; | 406 | stack_page = (unsigned long)task_stack_page(p); |
407 | BUG_ON(!stack_page); | 407 | BUG_ON(!stack_page); |
408 | 408 | ||
409 | /* | 409 | /* |
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c index 8ac74dddbbde..3c36c2d16148 100644 --- a/arch/avr32/kernel/ptrace.c +++ b/arch/avr32/kernel/ptrace.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | static struct pt_regs *get_user_regs(struct task_struct *tsk) | 25 | static struct pt_regs *get_user_regs(struct task_struct *tsk) |
26 | { | 26 | { |
27 | return (struct pt_regs *)((unsigned long) tsk->thread_info + | 27 | return (struct pt_regs *)((unsigned long)task_stack_page(tsk) + |
28 | THREAD_SIZE - sizeof(struct pt_regs)); | 28 | THREAD_SIZE - sizeof(struct pt_regs)); |
29 | } | 29 | } |
30 | 30 | ||
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index 7c279586fbba..07f6a6fa340d 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S | |||
@@ -291,4 +291,5 @@ sys_call_table: | |||
291 | .long sys_shmget /* 275 */ | 291 | .long sys_shmget /* 275 */ |
292 | .long sys_shmdt | 292 | .long sys_shmdt |
293 | .long sys_shmctl | 293 | .long sys_shmctl |
294 | .long sys_utimensat | ||
294 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ | 295 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ |
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c index 4de9edf96ed2..86d107511dd4 100644 --- a/arch/avr32/kernel/traps.c +++ b/arch/avr32/kernel/traps.c | |||
@@ -123,7 +123,7 @@ asmlinkage void do_address_exception(unsigned long ecr, struct pt_regs *regs) | |||
123 | 123 | ||
124 | /* This way of handling undefined instructions is stolen from ARM */ | 124 | /* This way of handling undefined instructions is stolen from ARM */ |
125 | static LIST_HEAD(undef_hook); | 125 | static LIST_HEAD(undef_hook); |
126 | static spinlock_t undef_lock = SPIN_LOCK_UNLOCKED; | 126 | static DEFINE_SPINLOCK(undef_lock); |
127 | 127 | ||
128 | void register_undef_hook(struct undef_hook *hook) | 128 | void register_undef_hook(struct undef_hook *hook) |
129 | { | 129 | { |
diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c index 7ad20cfb48a8..e7f72c995a32 100644 --- a/arch/avr32/kernel/vmlinux.lds.c +++ b/arch/avr32/kernel/vmlinux.lds.c | |||
@@ -35,7 +35,7 @@ SECTIONS | |||
35 | _einittext = .; | 35 | _einittext = .; |
36 | . = ALIGN(4); | 36 | . = ALIGN(4); |
37 | __tagtable_begin = .; | 37 | __tagtable_begin = .; |
38 | *(.taglist) | 38 | *(.taglist.init) |
39 | __tagtable_end = .; | 39 | __tagtable_end = .; |
40 | *(.init.data) | 40 | *(.init.data) |
41 | . = ALIGN(16); | 41 | . = ALIGN(16); |
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c index 00c435452d7e..0f8c89c9f832 100644 --- a/arch/avr32/mach-at32ap/clock.c +++ b/arch/avr32/mach-at32ap/clock.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #include "clock.h" | 19 | #include "clock.h" |
20 | 20 | ||
21 | static spinlock_t clk_lock = SPIN_LOCK_UNLOCKED; | 21 | static DEFINE_SPINLOCK(clk_lock); |
22 | 22 | ||
23 | struct clk *clk_get(struct device *dev, const char *id) | 23 | struct clk *clk_get(struct device *dev, const char *id) |
24 | { | 24 | { |
diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c index b68d669f823d..099212d4567c 100644 --- a/arch/avr32/mm/dma-coherent.c +++ b/arch/avr32/mm/dma-coherent.c | |||
@@ -112,16 +112,21 @@ void dma_free_coherent(struct device *dev, size_t size, | |||
112 | } | 112 | } |
113 | EXPORT_SYMBOL(dma_free_coherent); | 113 | EXPORT_SYMBOL(dma_free_coherent); |
114 | 114 | ||
115 | #if 0 | ||
116 | void *dma_alloc_writecombine(struct device *dev, size_t size, | 115 | void *dma_alloc_writecombine(struct device *dev, size_t size, |
117 | dma_addr_t *handle, gfp_t gfp) | 116 | dma_addr_t *handle, gfp_t gfp) |
118 | { | 117 | { |
119 | struct page *page; | 118 | struct page *page; |
119 | dma_addr_t phys; | ||
120 | 120 | ||
121 | page = __dma_alloc(dev, size, handle, gfp); | 121 | page = __dma_alloc(dev, size, handle, gfp); |
122 | if (!page) | ||
123 | return NULL; | ||
124 | |||
125 | phys = page_to_phys(page); | ||
126 | *handle = phys; | ||
122 | 127 | ||
123 | /* Now, map the page into P3 with write-combining turned on */ | 128 | /* Now, map the page into P3 with write-combining turned on */ |
124 | return __ioremap(page_to_phys(page), size, _PAGE_BUFFER); | 129 | return __ioremap(phys, size, _PAGE_BUFFER); |
125 | } | 130 | } |
126 | EXPORT_SYMBOL(dma_alloc_writecombine); | 131 | EXPORT_SYMBOL(dma_alloc_writecombine); |
127 | 132 | ||
@@ -132,8 +137,7 @@ void dma_free_writecombine(struct device *dev, size_t size, | |||
132 | 137 | ||
133 | iounmap(cpu_addr); | 138 | iounmap(cpu_addr); |
134 | 139 | ||
135 | page = bus_to_page(handle); | 140 | page = phys_to_page(handle); |
136 | __dma_free(dev, size, page, handle); | 141 | __dma_free(dev, size, page, handle); |
137 | } | 142 | } |
138 | EXPORT_SYMBOL(dma_free_writecombine); | 143 | EXPORT_SYMBOL(dma_free_writecombine); |
139 | #endif | ||
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c index 41d9a9f89700..e455f4504509 100644 --- a/arch/blackfin/kernel/asm-offsets.c +++ b/arch/blackfin/kernel/asm-offsets.c | |||
@@ -46,7 +46,7 @@ int main(void) | |||
46 | DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); | 46 | DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); |
47 | DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); | 47 | DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); |
48 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); | 48 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); |
49 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info)); | 49 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack)); |
50 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); | 50 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); |
51 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); | 51 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); |
52 | DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending)); | 52 | DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending)); |
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index d7c8e514cb92..e718bb4a1ef0 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -73,7 +73,7 @@ | |||
73 | static inline struct pt_regs *get_user_regs(struct task_struct *task) | 73 | static inline struct pt_regs *get_user_regs(struct task_struct *task) |
74 | { | 74 | { |
75 | return (struct pt_regs *) | 75 | return (struct pt_regs *) |
76 | ((unsigned long)task->thread_info + | 76 | ((unsigned long)task_stack_page(task) + |
77 | (THREAD_SIZE - sizeof(struct pt_regs))); | 77 | (THREAD_SIZE - sizeof(struct pt_regs))); |
78 | } | 78 | } |
79 | 79 | ||
@@ -99,7 +99,7 @@ static inline long get_reg(struct task_struct *task, int regno) | |||
99 | unsigned char *reg_ptr; | 99 | unsigned char *reg_ptr; |
100 | 100 | ||
101 | struct pt_regs *regs = | 101 | struct pt_regs *regs = |
102 | (struct pt_regs *)((unsigned long)task->thread_info + | 102 | (struct pt_regs *)((unsigned long)task_stack_page(task) + |
103 | (THREAD_SIZE - sizeof(struct pt_regs))); | 103 | (THREAD_SIZE - sizeof(struct pt_regs))); |
104 | reg_ptr = (char *)regs; | 104 | reg_ptr = (char *)regs; |
105 | 105 | ||
@@ -125,7 +125,7 @@ put_reg(struct task_struct *task, int regno, unsigned long data) | |||
125 | char * reg_ptr; | 125 | char * reg_ptr; |
126 | 126 | ||
127 | struct pt_regs *regs = | 127 | struct pt_regs *regs = |
128 | (struct pt_regs *)((unsigned long)task->thread_info + | 128 | (struct pt_regs *)((unsigned long)task_stack_page(task) + |
129 | (THREAD_SIZE - sizeof(struct pt_regs))); | 129 | (THREAD_SIZE - sizeof(struct pt_regs))); |
130 | reg_ptr = (char *)regs; | 130 | reg_ptr = (char *)regs; |
131 | 131 | ||
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index f64624fc4504..1d859c16931e 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig | |||
@@ -603,7 +603,7 @@ config ETRAX_CARDBUS | |||
603 | select HOTPLUG | 603 | select HOTPLUG |
604 | select PCCARD_NONSTATIC | 604 | select PCCARD_NONSTATIC |
605 | help | 605 | help |
606 | Enabled the ETRAX Carbus driver. | 606 | Enabled the ETRAX Cardbus driver. |
607 | 607 | ||
608 | config PCI | 608 | config PCI |
609 | bool | 609 | bool |
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index eed694312a79..114738a45582 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig | |||
@@ -45,15 +45,15 @@ config TIME_LOW_RES | |||
45 | bool | 45 | bool |
46 | default y | 46 | default y |
47 | 47 | ||
48 | config ARCH_HAS_ILOG2_U32 | 48 | config QUICKLIST |
49 | bool | 49 | bool |
50 | default y | 50 | default y |
51 | 51 | ||
52 | config ARCH_HAS_ILOG2_U64 | 52 | config ARCH_HAS_ILOG2_U32 |
53 | bool | 53 | bool |
54 | default y | 54 | default y |
55 | 55 | ||
56 | config ARCH_USES_SLAB_PAGE_STRUCT | 56 | config ARCH_HAS_ILOG2_U64 |
57 | bool | 57 | bool |
58 | default y | 58 | default y |
59 | 59 | ||
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 515a5cea5469..9583a338e9d6 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c | |||
@@ -25,12 +25,14 @@ | |||
25 | #include <linux/elf.h> | 25 | #include <linux/elf.h> |
26 | #include <linux/reboot.h> | 26 | #include <linux/reboot.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/pagemap.h> | ||
28 | 29 | ||
29 | #include <asm/asm-offsets.h> | 30 | #include <asm/asm-offsets.h> |
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
32 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
33 | #include <asm/pgtable.h> | 34 | #include <asm/pgtable.h> |
35 | #include <asm/tlb.h> | ||
34 | #include <asm/gdb-stub.h> | 36 | #include <asm/gdb-stub.h> |
35 | #include <asm/mb-regs.h> | 37 | #include <asm/mb-regs.h> |
36 | 38 | ||
@@ -88,6 +90,8 @@ void cpu_idle(void) | |||
88 | while (!need_resched()) { | 90 | while (!need_resched()) { |
89 | irq_stat[cpu].idle_timestamp = jiffies; | 91 | irq_stat[cpu].idle_timestamp = jiffies; |
90 | 92 | ||
93 | check_pgt_cache(); | ||
94 | |||
91 | if (!frv_dma_inprogress && idle) | 95 | if (!frv_dma_inprogress && idle) |
92 | idle(); | 96 | idle(); |
93 | } | 97 | } |
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c index 598a26ab8ad8..7787c3cc52c6 100644 --- a/arch/frv/mm/pgalloc.c +++ b/arch/frv/mm/pgalloc.c | |||
@@ -13,12 +13,12 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |
16 | #include <linux/quicklist.h> | ||
16 | #include <asm/pgalloc.h> | 17 | #include <asm/pgalloc.h> |
17 | #include <asm/page.h> | 18 | #include <asm/page.h> |
18 | #include <asm/cacheflush.h> | 19 | #include <asm/cacheflush.h> |
19 | 20 | ||
20 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); | 21 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); |
21 | struct kmem_cache *pgd_cache; | ||
22 | 22 | ||
23 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 23 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
24 | { | 24 | { |
@@ -100,7 +100,7 @@ static inline void pgd_list_del(pgd_t *pgd) | |||
100 | set_page_private(next, (unsigned long) pprev); | 100 | set_page_private(next, (unsigned long) pprev); |
101 | } | 101 | } |
102 | 102 | ||
103 | void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) | 103 | void pgd_ctor(void *pgd) |
104 | { | 104 | { |
105 | unsigned long flags; | 105 | unsigned long flags; |
106 | 106 | ||
@@ -120,7 +120,7 @@ void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | /* never called when PTRS_PER_PMD > 1 */ | 122 | /* never called when PTRS_PER_PMD > 1 */ |
123 | void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) | 123 | void pgd_dtor(void *pgd) |
124 | { | 124 | { |
125 | unsigned long flags; /* can be called from interrupt context */ | 125 | unsigned long flags; /* can be called from interrupt context */ |
126 | 126 | ||
@@ -133,7 +133,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
133 | { | 133 | { |
134 | pgd_t *pgd; | 134 | pgd_t *pgd; |
135 | 135 | ||
136 | pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL); | 136 | pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); |
137 | if (!pgd) | 137 | if (!pgd) |
138 | return pgd; | 138 | return pgd; |
139 | 139 | ||
@@ -143,15 +143,15 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
143 | void pgd_free(pgd_t *pgd) | 143 | void pgd_free(pgd_t *pgd) |
144 | { | 144 | { |
145 | /* in the non-PAE case, clear_page_tables() clears user pgd entries */ | 145 | /* in the non-PAE case, clear_page_tables() clears user pgd entries */ |
146 | kmem_cache_free(pgd_cache, pgd); | 146 | quicklist_free(0, pgd_dtor, pgd); |
147 | } | 147 | } |
148 | 148 | ||
149 | void __init pgtable_cache_init(void) | 149 | void __init pgtable_cache_init(void) |
150 | { | 150 | { |
151 | pgd_cache = kmem_cache_create("pgd", | ||
152 | PTRS_PER_PGD * sizeof(pgd_t), | ||
153 | PTRS_PER_PGD * sizeof(pgd_t), | ||
154 | SLAB_PANIC, | ||
155 | pgd_ctor, | ||
156 | pgd_dtor); | ||
157 | } | 151 | } |
152 | |||
153 | void check_pgt_cache(void) | ||
154 | { | ||
155 | quicklist_trim(0, pgd_dtor, 25, 16); | ||
156 | } | ||
157 | |||
diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug index e0e9bcb015a9..554efe604a08 100644 --- a/arch/h8300/Kconfig.debug +++ b/arch/h8300/Kconfig.debug | |||
@@ -21,12 +21,12 @@ config GDB_MAGICPRINT | |||
21 | bool "Message Output for GDB MagicPrint service" | 21 | bool "Message Output for GDB MagicPrint service" |
22 | depends on (H8300H_SIM || H8S_SIM) | 22 | depends on (H8300H_SIM || H8S_SIM) |
23 | help | 23 | help |
24 | kernel messages output useing MagicPrint service from GDB | 24 | kernel messages output using MagicPrint service from GDB |
25 | 25 | ||
26 | config SYSCALL_PRINT | 26 | config SYSCALL_PRINT |
27 | bool "SystemCall trace print" | 27 | bool "SystemCall trace print" |
28 | help | 28 | help |
29 | outout history of systemcall | 29 | output history of systemcall |
30 | 30 | ||
31 | config GDB_DEBUG | 31 | config GDB_DEBUG |
32 | bool "Use gdb stub" | 32 | bool "Use gdb stub" |
diff --git a/arch/h8300/kernel/asm-offsets.c b/arch/h8300/kernel/asm-offsets.c index b78b82ad28a3..fc30b4fd0914 100644 --- a/arch/h8300/kernel/asm-offsets.c +++ b/arch/h8300/kernel/asm-offsets.c | |||
@@ -30,7 +30,7 @@ int main(void) | |||
30 | DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); | 30 | DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); |
31 | DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); | 31 | DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); |
32 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); | 32 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); |
33 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info)); | 33 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack)); |
34 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); | 34 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); |
35 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); | 35 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); |
36 | 36 | ||
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 64ad10f984a1..30944ee2e61a 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -858,9 +858,9 @@ config RELOCATABLE | |||
858 | bool "Build a relocatable kernel(EXPERIMENTAL)" | 858 | bool "Build a relocatable kernel(EXPERIMENTAL)" |
859 | depends on EXPERIMENTAL | 859 | depends on EXPERIMENTAL |
860 | help | 860 | help |
861 | This build a kernel image that retains relocation information | 861 | This builds a kernel image that retains relocation information |
862 | so it can be loaded someplace besides the default 1MB. | 862 | so it can be loaded someplace besides the default 1MB. |
863 | The relocations tend to the kernel binary about 10% larger, | 863 | The relocations tend to make the kernel binary about 10% larger, |
864 | but are discarded at runtime. | 864 | but are discarded at runtime. |
865 | 865 | ||
866 | One use is for the kexec on panic case where the recovery kernel | 866 | One use is for the kexec on panic case where the recovery kernel |
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index dce6124cb842..d7f6fb0b30f2 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu | |||
@@ -108,7 +108,7 @@ config MCORE2 | |||
108 | bool "Core 2/newer Xeon" | 108 | bool "Core 2/newer Xeon" |
109 | help | 109 | help |
110 | Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) | 110 | Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) |
111 | CPUs. You can distingush newer from older Xeons by the CPU family | 111 | CPUs. You can distinguish newer from older Xeons by the CPU family |
112 | in /proc/cpuinfo. Newer ones have 6. | 112 | in /proc/cpuinfo. Newer ones have 6. |
113 | 113 | ||
114 | config MPENTIUM4 | 114 | config MPENTIUM4 |
@@ -172,7 +172,7 @@ config MWINCHIP3D | |||
172 | help | 172 | help |
173 | Select this for an IDT Winchip-2A or 3. Linux and GCC | 173 | Select this for an IDT Winchip-2A or 3. Linux and GCC |
174 | treat this chip as a 586TSC with some extended instructions | 174 | treat this chip as a 586TSC with some extended instructions |
175 | and alignment reqirements. Also enable out of order memory | 175 | and alignment requirements. Also enable out of order memory |
176 | stores for this CPU, which can increase performance of some | 176 | stores for this CPU, which can increase performance of some |
177 | operations. | 177 | operations. |
178 | 178 | ||
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 80b4c5d421b1..e5be819492ef 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -733,9 +733,11 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, | |||
733 | sys_dev = get_cpu_sysdev(cpu); | 733 | sys_dev = get_cpu_sysdev(cpu); |
734 | switch (action) { | 734 | switch (action) { |
735 | case CPU_ONLINE: | 735 | case CPU_ONLINE: |
736 | case CPU_ONLINE_FROZEN: | ||
736 | cache_add_dev(sys_dev); | 737 | cache_add_dev(sys_dev); |
737 | break; | 738 | break; |
738 | case CPU_DEAD: | 739 | case CPU_DEAD: |
740 | case CPU_DEAD_FROZEN: | ||
739 | cache_remove_dev(sys_dev); | 741 | cache_remove_dev(sys_dev); |
740 | break; | 742 | break; |
741 | } | 743 | } |
diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c index 065005c3f168..7ba7c3abd3a4 100644 --- a/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/i386/kerne/cpu/mcheck/therm_throt.c | 2 | * linux/arch/i386/kernel/cpu/mcheck/therm_throt.c |
3 | * | 3 | * |
4 | * Thermal throttle event support code (such as syslog messaging and rate | 4 | * Thermal throttle event support code (such as syslog messaging and rate |
5 | * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). | 5 | * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). |
@@ -137,10 +137,12 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, | |||
137 | mutex_lock(&therm_cpu_lock); | 137 | mutex_lock(&therm_cpu_lock); |
138 | switch (action) { | 138 | switch (action) { |
139 | case CPU_ONLINE: | 139 | case CPU_ONLINE: |
140 | case CPU_ONLINE_FROZEN: | ||
140 | err = thermal_throttle_add_dev(sys_dev); | 141 | err = thermal_throttle_add_dev(sys_dev); |
141 | WARN_ON(err); | 142 | WARN_ON(err); |
142 | break; | 143 | break; |
143 | case CPU_DEAD: | 144 | case CPU_DEAD: |
145 | case CPU_DEAD_FROZEN: | ||
144 | thermal_throttle_remove_dev(sys_dev); | 146 | thermal_throttle_remove_dev(sys_dev); |
145 | break; | 147 | break; |
146 | } | 148 | } |
diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c index 6471a5a13202..200fb3f9ebfb 100644 --- a/arch/i386/kernel/cpu/transmeta.c +++ b/arch/i386/kernel/cpu/transmeta.c | |||
@@ -77,8 +77,10 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) | |||
77 | set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); | 77 | set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); |
78 | 78 | ||
79 | /* If we can run i686 user-space code, call us an i686 */ | 79 | /* If we can run i686 user-space code, call us an i686 */ |
80 | #define USER686 (X86_FEATURE_TSC|X86_FEATURE_CX8|X86_FEATURE_CMOV) | 80 | #define USER686 ((1 << X86_FEATURE_TSC)|\ |
81 | if ( c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686 ) | 81 | (1 << X86_FEATURE_CX8)|\ |
82 | (1 << X86_FEATURE_CMOV)) | ||
83 | if (c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686) | ||
82 | c->x86 = 6; | 84 | c->x86 = 6; |
83 | 85 | ||
84 | #ifdef CONFIG_SYSCTL | 86 | #ifdef CONFIG_SYSCTL |
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index eeae0d992337..5c2faa10e9fa 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c | |||
@@ -169,9 +169,11 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac | |||
169 | 169 | ||
170 | switch (action) { | 170 | switch (action) { |
171 | case CPU_ONLINE: | 171 | case CPU_ONLINE: |
172 | case CPU_ONLINE_FROZEN: | ||
172 | cpuid_device_create(cpu); | 173 | cpuid_device_create(cpu); |
173 | break; | 174 | break; |
174 | case CPU_DEAD: | 175 | case CPU_DEAD: |
176 | case CPU_DEAD_FROZEN: | ||
175 | device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); | 177 | device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); |
176 | break; | 178 | break; |
177 | } | 179 | } |
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index cbe7ec8dbb9f..83f825f2e2d7 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c | |||
@@ -567,7 +567,7 @@ static int cpu_request_microcode(int cpu) | |||
567 | return error; | 567 | return error; |
568 | } | 568 | } |
569 | 569 | ||
570 | static int apply_microcode_on_cpu(int cpu) | 570 | static int apply_microcode_check_cpu(int cpu) |
571 | { | 571 | { |
572 | struct cpuinfo_x86 *c = cpu_data + cpu; | 572 | struct cpuinfo_x86 *c = cpu_data + cpu; |
573 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 573 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
@@ -575,8 +575,9 @@ static int apply_microcode_on_cpu(int cpu) | |||
575 | unsigned int val[2]; | 575 | unsigned int val[2]; |
576 | int err = 0; | 576 | int err = 0; |
577 | 577 | ||
578 | /* Check if the microcode is available */ | ||
578 | if (!uci->mc) | 579 | if (!uci->mc) |
579 | return -EINVAL; | 580 | return 0; |
580 | 581 | ||
581 | old = current->cpus_allowed; | 582 | old = current->cpus_allowed; |
582 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 583 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
@@ -614,7 +615,7 @@ static int apply_microcode_on_cpu(int cpu) | |||
614 | return err; | 615 | return err; |
615 | } | 616 | } |
616 | 617 | ||
617 | static void microcode_init_cpu(int cpu) | 618 | static void microcode_init_cpu(int cpu, int resume) |
618 | { | 619 | { |
619 | cpumask_t old; | 620 | cpumask_t old; |
620 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 621 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
@@ -624,8 +625,7 @@ static void microcode_init_cpu(int cpu) | |||
624 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 625 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
625 | mutex_lock(µcode_mutex); | 626 | mutex_lock(µcode_mutex); |
626 | collect_cpu_info(cpu); | 627 | collect_cpu_info(cpu); |
627 | if (uci->valid && system_state == SYSTEM_RUNNING && | 628 | if (uci->valid && system_state == SYSTEM_RUNNING && !resume) |
628 | !suspend_cpu_hotplug) | ||
629 | cpu_request_microcode(cpu); | 629 | cpu_request_microcode(cpu); |
630 | mutex_unlock(µcode_mutex); | 630 | mutex_unlock(µcode_mutex); |
631 | set_cpus_allowed(current, old); | 631 | set_cpus_allowed(current, old); |
@@ -702,7 +702,7 @@ static struct attribute_group mc_attr_group = { | |||
702 | .name = "microcode", | 702 | .name = "microcode", |
703 | }; | 703 | }; |
704 | 704 | ||
705 | static int mc_sysdev_add(struct sys_device *sys_dev) | 705 | static int __mc_sysdev_add(struct sys_device *sys_dev, int resume) |
706 | { | 706 | { |
707 | int err, cpu = sys_dev->id; | 707 | int err, cpu = sys_dev->id; |
708 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 708 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
@@ -711,39 +711,31 @@ static int mc_sysdev_add(struct sys_device *sys_dev) | |||
711 | return 0; | 711 | return 0; |
712 | 712 | ||
713 | pr_debug("Microcode:CPU %d added\n", cpu); | 713 | pr_debug("Microcode:CPU %d added\n", cpu); |
714 | /* If suspend_cpu_hotplug is set, the system is resuming and we should | 714 | memset(uci, 0, sizeof(*uci)); |
715 | * use the data from before the suspend. | ||
716 | */ | ||
717 | if (suspend_cpu_hotplug) { | ||
718 | err = apply_microcode_on_cpu(cpu); | ||
719 | if (err) | ||
720 | microcode_fini_cpu(cpu); | ||
721 | } | ||
722 | if (!uci->valid) | ||
723 | memset(uci, 0, sizeof(*uci)); | ||
724 | 715 | ||
725 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); | 716 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); |
726 | if (err) | 717 | if (err) |
727 | return err; | 718 | return err; |
728 | 719 | ||
729 | if (!uci->valid) | 720 | microcode_init_cpu(cpu, resume); |
730 | microcode_init_cpu(cpu); | ||
731 | 721 | ||
732 | return 0; | 722 | return 0; |
733 | } | 723 | } |
734 | 724 | ||
725 | static int mc_sysdev_add(struct sys_device *sys_dev) | ||
726 | { | ||
727 | return __mc_sysdev_add(sys_dev, 0); | ||
728 | } | ||
729 | |||
735 | static int mc_sysdev_remove(struct sys_device *sys_dev) | 730 | static int mc_sysdev_remove(struct sys_device *sys_dev) |
736 | { | 731 | { |
737 | int cpu = sys_dev->id; | 732 | int cpu = sys_dev->id; |
738 | 733 | ||
739 | if (!cpu_online(cpu)) | 734 | if (!cpu_online(cpu)) |
740 | return 0; | 735 | return 0; |
736 | |||
741 | pr_debug("Microcode:CPU %d removed\n", cpu); | 737 | pr_debug("Microcode:CPU %d removed\n", cpu); |
742 | /* If suspend_cpu_hotplug is set, the system is suspending and we should | 738 | microcode_fini_cpu(cpu); |
743 | * keep the microcode in memory for the resume. | ||
744 | */ | ||
745 | if (!suspend_cpu_hotplug) | ||
746 | microcode_fini_cpu(cpu); | ||
747 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); | 739 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); |
748 | return 0; | 740 | return 0; |
749 | } | 741 | } |
@@ -774,13 +766,34 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | |||
774 | 766 | ||
775 | sys_dev = get_cpu_sysdev(cpu); | 767 | sys_dev = get_cpu_sysdev(cpu); |
776 | switch (action) { | 768 | switch (action) { |
769 | case CPU_UP_CANCELED_FROZEN: | ||
770 | /* The CPU refused to come up during a system resume */ | ||
771 | microcode_fini_cpu(cpu); | ||
772 | break; | ||
777 | case CPU_ONLINE: | 773 | case CPU_ONLINE: |
778 | case CPU_DOWN_FAILED: | 774 | case CPU_DOWN_FAILED: |
779 | mc_sysdev_add(sys_dev); | 775 | mc_sysdev_add(sys_dev); |
780 | break; | 776 | break; |
777 | case CPU_ONLINE_FROZEN: | ||
778 | /* System-wide resume is in progress, try to apply microcode */ | ||
779 | if (apply_microcode_check_cpu(cpu)) { | ||
780 | /* The application of microcode failed */ | ||
781 | microcode_fini_cpu(cpu); | ||
782 | __mc_sysdev_add(sys_dev, 1); | ||
783 | break; | ||
784 | } | ||
785 | case CPU_DOWN_FAILED_FROZEN: | ||
786 | if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group)) | ||
787 | printk(KERN_ERR "Microcode: Failed to create the sysfs " | ||
788 | "group for CPU%d\n", cpu); | ||
789 | break; | ||
781 | case CPU_DOWN_PREPARE: | 790 | case CPU_DOWN_PREPARE: |
782 | mc_sysdev_remove(sys_dev); | 791 | mc_sysdev_remove(sys_dev); |
783 | break; | 792 | break; |
793 | case CPU_DOWN_PREPARE_FROZEN: | ||
794 | /* Suspend is in progress, only remove the interface */ | ||
795 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); | ||
796 | break; | ||
784 | } | 797 | } |
785 | return NOTIFY_OK; | 798 | return NOTIFY_OK; |
786 | } | 799 | } |
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 8cd0a91ce107..0c1069b8d638 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c | |||
@@ -153,9 +153,11 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, | |||
153 | 153 | ||
154 | switch (action) { | 154 | switch (action) { |
155 | case CPU_ONLINE: | 155 | case CPU_ONLINE: |
156 | case CPU_ONLINE_FROZEN: | ||
156 | msr_device_create(cpu); | 157 | msr_device_create(cpu); |
157 | break; | 158 | break; |
158 | case CPU_DEAD: | 159 | case CPU_DEAD: |
160 | case CPU_DEAD_FROZEN: | ||
159 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 161 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); |
160 | break; | 162 | break; |
161 | } | 163 | } |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 4bec0cbf407a..c05e7e861b29 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -305,7 +305,7 @@ void show_registers(struct pt_regs *regs) | |||
305 | regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss); | 305 | regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss); |
306 | printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", | 306 | printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", |
307 | TASK_COMM_LEN, current->comm, current->pid, | 307 | TASK_COMM_LEN, current->comm, current->pid, |
308 | current_thread_info(), current, current->thread_info); | 308 | current_thread_info(), current, task_thread_info(current)); |
309 | /* | 309 | /* |
310 | * When in-kernel, we also print out the stack and code at the | 310 | * When in-kernel, we also print out the stack and code at the |
311 | * time of the fault.. | 311 | * time of the fault.. |
diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c index a7b3999bb37a..74f3da634423 100644 --- a/arch/i386/mach-generic/probe.c +++ b/arch/i386/mach-generic/probe.c | |||
@@ -119,9 +119,7 @@ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | #ifdef CONFIG_SMP | ||
123 | int hard_smp_processor_id(void) | 122 | int hard_smp_processor_id(void) |
124 | { | 123 | { |
125 | return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID)); | 124 | return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID)); |
126 | } | 125 | } |
127 | #endif | ||
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index 8fe7e4593d5f..9b77b39b71a6 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c | |||
@@ -292,8 +292,8 @@ machine_emergency_restart(void) | |||
292 | void | 292 | void |
293 | mca_nmi_hook(void) | 293 | mca_nmi_hook(void) |
294 | { | 294 | { |
295 | __u8 dumpval __attribute__((unused)) = inb(0xf823); | 295 | __u8 dumpval __maybe_unused = inb(0xf823); |
296 | __u8 swnmi __attribute__((unused)) = inb(0xf813); | 296 | __u8 swnmi __maybe_unused = inb(0xf813); |
297 | 297 | ||
298 | /* FIXME: assume dump switch pressed */ | 298 | /* FIXME: assume dump switch pressed */ |
299 | /* check to see if the dump switch was pressed */ | 299 | /* check to see if the dump switch was pressed */ |
diff --git a/arch/i386/pci/init.c b/arch/i386/pci/init.c index 1cf11af96de2..3de9f9ba2da6 100644 --- a/arch/i386/pci/init.c +++ b/arch/i386/pci/init.c | |||
@@ -6,7 +6,7 @@ | |||
6 | in the right sequence from here. */ | 6 | in the right sequence from here. */ |
7 | static __init int pci_access_init(void) | 7 | static __init int pci_access_init(void) |
8 | { | 8 | { |
9 | int type __attribute__((unused)) = 0; | 9 | int type __maybe_unused = 0; |
10 | 10 | ||
11 | #ifdef CONFIG_PCI_DIRECT | 11 | #ifdef CONFIG_PCI_DIRECT |
12 | type = pci_direct_probe(); | 12 | type = pci_direct_probe(); |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index e23af4b6ae8c..6e41471449c0 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -468,7 +468,7 @@ config KEXEC | |||
468 | help | 468 | help |
469 | kexec is a system call that implements the ability to shutdown your | 469 | kexec is a system call that implements the ability to shutdown your |
470 | current kernel, and to start another kernel. It is like a reboot | 470 | current kernel, and to start another kernel. It is like a reboot |
471 | but it is indepedent of the system firmware. And like a reboot | 471 | but it is independent of the system firmware. And like a reboot |
472 | you can start any kernel with it, not just Linux. | 472 | you can start any kernel with it, not just Linux. |
473 | 473 | ||
474 | The name comes from the similiarity to the exec system call. | 474 | The name comes from the similiarity to the exec system call. |
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index 687e5fdc9683..99b665e2b1d5 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S | |||
@@ -52,43 +52,6 @@ ENTRY(ia32_clone) | |||
52 | br.ret.sptk.many rp | 52 | br.ret.sptk.many rp |
53 | END(ia32_clone) | 53 | END(ia32_clone) |
54 | 54 | ||
55 | ENTRY(sys32_rt_sigsuspend) | ||
56 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) | ||
57 | alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs | ||
58 | mov loc0=rp | ||
59 | mov out0=in0 // mask | ||
60 | mov out1=in1 // sigsetsize | ||
61 | mov out2=sp // out2 = &sigscratch | ||
62 | .fframe 16 | ||
63 | adds sp=-16,sp // allocate dummy "sigscratch" | ||
64 | ;; | ||
65 | .body | ||
66 | br.call.sptk.many rp=ia32_rt_sigsuspend | ||
67 | 1: .restore sp | ||
68 | adds sp=16,sp | ||
69 | mov rp=loc0 | ||
70 | mov ar.pfs=loc1 | ||
71 | br.ret.sptk.many rp | ||
72 | END(sys32_rt_sigsuspend) | ||
73 | |||
74 | ENTRY(sys32_sigsuspend) | ||
75 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) | ||
76 | alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs | ||
77 | mov loc0=rp | ||
78 | mov out0=in2 // mask (first two args are ignored) | ||
79 | ;; | ||
80 | mov out1=sp // out1 = &sigscratch | ||
81 | .fframe 16 | ||
82 | adds sp=-16,sp // allocate dummy "sigscratch" | ||
83 | .body | ||
84 | br.call.sptk.many rp=ia32_sigsuspend | ||
85 | 1: .restore sp | ||
86 | adds sp=16,sp | ||
87 | mov rp=loc0 | ||
88 | mov ar.pfs=loc1 | ||
89 | br.ret.sptk.many rp | ||
90 | END(sys32_sigsuspend) | ||
91 | |||
92 | GLOBAL_ENTRY(ia32_ret_from_clone) | 55 | GLOBAL_ENTRY(ia32_ret_from_clone) |
93 | PT_REGS_UNWIND_INFO(0) | 56 | PT_REGS_UNWIND_INFO(0) |
94 | { /* | 57 | { /* |
@@ -389,7 +352,7 @@ ia32_syscall_table: | |||
389 | data8 sys_rt_sigpending | 352 | data8 sys_rt_sigpending |
390 | data8 compat_sys_rt_sigtimedwait | 353 | data8 compat_sys_rt_sigtimedwait |
391 | data8 sys32_rt_sigqueueinfo | 354 | data8 sys32_rt_sigqueueinfo |
392 | data8 sys32_rt_sigsuspend | 355 | data8 compat_sys_rt_sigsuspend |
393 | data8 sys32_pread /* 180 */ | 356 | data8 sys32_pread /* 180 */ |
394 | data8 sys32_pwrite | 357 | data8 sys32_pwrite |
395 | data8 sys_chown /* 16-bit version */ | 358 | data8 sys_chown /* 16-bit version */ |
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c index 10510e585204..85e82f32e480 100644 --- a/arch/ia64/ia32/ia32_signal.c +++ b/arch/ia64/ia32/ia32_signal.c | |||
@@ -451,59 +451,20 @@ sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int r | |||
451 | sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); | 451 | sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler); |
452 | } | 452 | } |
453 | 453 | ||
454 | long | 454 | asmlinkage long |
455 | __ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr) | 455 | sys32_sigsuspend (int history0, int history1, old_sigset_t mask) |
456 | { | 456 | { |
457 | extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall); | 457 | mask &= _BLOCKABLE; |
458 | sigset_t oldset, set; | ||
459 | |||
460 | scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */ | ||
461 | memset(&set, 0, sizeof(set)); | ||
462 | |||
463 | memcpy(&set.sig, &sset->sig, sigsetsize); | ||
464 | |||
465 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
466 | |||
467 | spin_lock_irq(¤t->sighand->siglock); | 458 | spin_lock_irq(¤t->sighand->siglock); |
468 | { | 459 | current->saved_sigmask = current->blocked; |
469 | oldset = current->blocked; | 460 | siginitset(¤t->blocked, mask); |
470 | current->blocked = set; | 461 | recalc_sigpending(); |
471 | recalc_sigpending(); | ||
472 | } | ||
473 | spin_unlock_irq(¤t->sighand->siglock); | 462 | spin_unlock_irq(¤t->sighand->siglock); |
474 | 463 | ||
475 | /* | 464 | current->state = TASK_INTERRUPTIBLE; |
476 | * The return below usually returns to the signal handler. We need to pre-set the | 465 | schedule(); |
477 | * correct error code here to ensure that the right values get saved in sigcontext | 466 | set_thread_flag(TIF_RESTORE_SIGMASK); |
478 | * by ia64_do_signal. | 467 | return -ERESTARTNOHAND; |
479 | */ | ||
480 | scr->pt.r8 = -EINTR; | ||
481 | while (1) { | ||
482 | current->state = TASK_INTERRUPTIBLE; | ||
483 | schedule(); | ||
484 | if (ia64_do_signal(&oldset, scr, 1)) | ||
485 | return -EINTR; | ||
486 | } | ||
487 | } | ||
488 | |||
489 | asmlinkage long | ||
490 | ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr) | ||
491 | { | ||
492 | compat_sigset_t set; | ||
493 | |||
494 | if (sigsetsize > sizeof(compat_sigset_t)) | ||
495 | return -EINVAL; | ||
496 | |||
497 | if (copy_from_user(&set.sig, &uset->sig, sigsetsize)) | ||
498 | return -EFAULT; | ||
499 | |||
500 | return __ia32_rt_sigsuspend(&set, sigsetsize, scr); | ||
501 | } | ||
502 | |||
503 | asmlinkage long | ||
504 | ia32_sigsuspend (unsigned int mask, struct sigscratch *scr) | ||
505 | { | ||
506 | return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr); | ||
507 | } | 468 | } |
508 | 469 | ||
509 | asmlinkage long | 470 | asmlinkage long |
@@ -810,7 +771,11 @@ get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
810 | } | 771 | } |
811 | /* Legacy stack switching not supported */ | 772 | /* Legacy stack switching not supported */ |
812 | 773 | ||
813 | return (void __user *)((esp - frame_size) & -8ul); | 774 | esp -= frame_size; |
775 | /* Align the stack pointer according to the i386 ABI, | ||
776 | * i.e. so that on function entry ((sp + 4) & 15) == 0. */ | ||
777 | esp = ((esp + 4) & -16ul) - 4; | ||
778 | return (void __user *) esp; | ||
814 | } | 779 | } |
815 | 780 | ||
816 | static int | 781 | static int |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 55fd2d5471e1..b50bf208678e 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1199,32 +1199,6 @@ ENTRY(notify_resume_user) | |||
1199 | br.ret.sptk.many rp | 1199 | br.ret.sptk.many rp |
1200 | END(notify_resume_user) | 1200 | END(notify_resume_user) |
1201 | 1201 | ||
1202 | GLOBAL_ENTRY(sys_rt_sigsuspend) | ||
1203 | .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) | ||
1204 | alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart! | ||
1205 | mov r9=ar.unat | ||
1206 | mov loc0=rp // save return address | ||
1207 | mov out0=in0 // mask | ||
1208 | mov out1=in1 // sigsetsize | ||
1209 | adds out2=8,sp // out2=&sigscratch->ar_pfs | ||
1210 | ;; | ||
1211 | .fframe 16 | ||
1212 | .spillsp ar.unat, 16 | ||
1213 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it | ||
1214 | st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch | ||
1215 | .body | ||
1216 | br.call.sptk.many rp=ia64_rt_sigsuspend | ||
1217 | .ret17: .restore sp | ||
1218 | adds sp=16,sp // pop scratch stack space | ||
1219 | ;; | ||
1220 | ld8 r9=[sp] // load new unat from sw->caller_unat | ||
1221 | mov rp=loc0 | ||
1222 | ;; | ||
1223 | mov ar.unat=r9 | ||
1224 | mov ar.pfs=loc1 | ||
1225 | br.ret.sptk.many rp | ||
1226 | END(sys_rt_sigsuspend) | ||
1227 | |||
1228 | ENTRY(sys_rt_sigreturn) | 1202 | ENTRY(sys_rt_sigreturn) |
1229 | PT_REGS_UNWIND_INFO(0) | 1203 | PT_REGS_UNWIND_INFO(0) |
1230 | /* | 1204 | /* |
@@ -1598,8 +1572,8 @@ sys_call_table: | |||
1598 | data8 sys_readlinkat | 1572 | data8 sys_readlinkat |
1599 | data8 sys_fchmodat | 1573 | data8 sys_fchmodat |
1600 | data8 sys_faccessat | 1574 | data8 sys_faccessat |
1601 | data8 sys_ni_syscall // reserved for pselect | 1575 | data8 sys_pselect6 |
1602 | data8 sys_ni_syscall // 1295 reserved for ppoll | 1576 | data8 sys_ppoll |
1603 | data8 sys_unshare | 1577 | data8 sys_unshare |
1604 | data8 sys_splice | 1578 | data8 sys_splice |
1605 | data8 sys_set_robust_list | 1579 | data8 sys_set_robust_list |
diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c index d3e9f33e8bdd..6a49600cf337 100644 --- a/arch/ia64/kernel/err_inject.c +++ b/arch/ia64/kernel/err_inject.c | |||
@@ -236,9 +236,11 @@ static int __cpuinit err_inject_cpu_callback(struct notifier_block *nfb, | |||
236 | sys_dev = get_cpu_sysdev(cpu); | 236 | sys_dev = get_cpu_sysdev(cpu); |
237 | switch (action) { | 237 | switch (action) { |
238 | case CPU_ONLINE: | 238 | case CPU_ONLINE: |
239 | case CPU_ONLINE_FROZEN: | ||
239 | err_inject_add_dev(sys_dev); | 240 | err_inject_add_dev(sys_dev); |
240 | break; | 241 | break; |
241 | case CPU_DEAD: | 242 | case CPU_DEAD: |
243 | case CPU_DEAD_FROZEN: | ||
242 | err_inject_remove_dev(sys_dev); | 244 | err_inject_remove_dev(sys_dev); |
243 | break; | 245 | break; |
244 | } | 246 | } |
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 93d9ab14ba24..37f46527d233 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -1012,7 +1012,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, | |||
1012 | /* | 1012 | /* |
1013 | * ACPI calls this when it finds an entry for a legacy ISA IRQ override. | 1013 | * ACPI calls this when it finds an entry for a legacy ISA IRQ override. |
1014 | */ | 1014 | */ |
1015 | void __init | 1015 | void __devinit |
1016 | iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, | 1016 | iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, |
1017 | unsigned long polarity, | 1017 | unsigned long polarity, |
1018 | unsigned long trigger) | 1018 | unsigned long trigger) |
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 1c5044a80958..bc47049f060f 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/machvec.h> | 38 | #include <asm/machvec.h> |
39 | #include <asm/pgtable.h> | 39 | #include <asm/pgtable.h> |
40 | #include <asm/system.h> | 40 | #include <asm/system.h> |
41 | #include <asm/tlbflush.h> | ||
41 | 42 | ||
42 | #ifdef CONFIG_PERFMON | 43 | #ifdef CONFIG_PERFMON |
43 | # include <asm/perfmon.h> | 44 | # include <asm/perfmon.h> |
@@ -126,8 +127,10 @@ void destroy_irq(unsigned int irq) | |||
126 | 127 | ||
127 | #ifdef CONFIG_SMP | 128 | #ifdef CONFIG_SMP |
128 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) | 129 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) |
130 | # define IS_LOCAL_TLB_FLUSH(vec) (vec == IA64_IPI_LOCAL_TLB_FLUSH) | ||
129 | #else | 131 | #else |
130 | # define IS_RESCHEDULE(vec) (0) | 132 | # define IS_RESCHEDULE(vec) (0) |
133 | # define IS_LOCAL_TLB_FLUSH(vec) (0) | ||
131 | #endif | 134 | #endif |
132 | /* | 135 | /* |
133 | * That's where the IVT branches when we get an external | 136 | * That's where the IVT branches when we get an external |
@@ -179,8 +182,11 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) | |||
179 | saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); | 182 | saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); |
180 | ia64_srlz_d(); | 183 | ia64_srlz_d(); |
181 | while (vector != IA64_SPURIOUS_INT_VECTOR) { | 184 | while (vector != IA64_SPURIOUS_INT_VECTOR) { |
182 | if (unlikely(IS_RESCHEDULE(vector))) | 185 | if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) { |
183 | kstat_this_cpu.irqs[vector]++; | 186 | smp_local_flush_tlb(); |
187 | kstat_this_cpu.irqs[vector]++; | ||
188 | } else if (unlikely(IS_RESCHEDULE(vector))) | ||
189 | kstat_this_cpu.irqs[vector]++; | ||
184 | else { | 190 | else { |
185 | ia64_setreg(_IA64_REG_CR_TPR, vector); | 191 | ia64_setreg(_IA64_REG_CR_TPR, vector); |
186 | ia64_srlz_d(); | 192 | ia64_srlz_d(); |
@@ -226,8 +232,11 @@ void ia64_process_pending_intr(void) | |||
226 | * Perform normal interrupt style processing | 232 | * Perform normal interrupt style processing |
227 | */ | 233 | */ |
228 | while (vector != IA64_SPURIOUS_INT_VECTOR) { | 234 | while (vector != IA64_SPURIOUS_INT_VECTOR) { |
229 | if (unlikely(IS_RESCHEDULE(vector))) | 235 | if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) { |
230 | kstat_this_cpu.irqs[vector]++; | 236 | smp_local_flush_tlb(); |
237 | kstat_this_cpu.irqs[vector]++; | ||
238 | } else if (unlikely(IS_RESCHEDULE(vector))) | ||
239 | kstat_this_cpu.irqs[vector]++; | ||
231 | else { | 240 | else { |
232 | struct pt_regs *old_regs = set_irq_regs(NULL); | 241 | struct pt_regs *old_regs = set_irq_regs(NULL); |
233 | 242 | ||
@@ -259,12 +268,12 @@ void ia64_process_pending_intr(void) | |||
259 | 268 | ||
260 | 269 | ||
261 | #ifdef CONFIG_SMP | 270 | #ifdef CONFIG_SMP |
262 | extern irqreturn_t handle_IPI (int irq, void *dev_id); | ||
263 | 271 | ||
264 | static irqreturn_t dummy_handler (int irq, void *dev_id) | 272 | static irqreturn_t dummy_handler (int irq, void *dev_id) |
265 | { | 273 | { |
266 | BUG(); | 274 | BUG(); |
267 | } | 275 | } |
276 | extern irqreturn_t handle_IPI (int irq, void *dev_id); | ||
268 | 277 | ||
269 | static struct irqaction ipi_irqaction = { | 278 | static struct irqaction ipi_irqaction = { |
270 | .handler = handle_IPI, | 279 | .handler = handle_IPI, |
@@ -277,6 +286,13 @@ static struct irqaction resched_irqaction = { | |||
277 | .flags = IRQF_DISABLED, | 286 | .flags = IRQF_DISABLED, |
278 | .name = "resched" | 287 | .name = "resched" |
279 | }; | 288 | }; |
289 | |||
290 | static struct irqaction tlb_irqaction = { | ||
291 | .handler = dummy_handler, | ||
292 | .flags = IRQF_DISABLED, | ||
293 | .name = "tlb_flush" | ||
294 | }; | ||
295 | |||
280 | #endif | 296 | #endif |
281 | 297 | ||
282 | void | 298 | void |
@@ -302,6 +318,7 @@ init_IRQ (void) | |||
302 | #ifdef CONFIG_SMP | 318 | #ifdef CONFIG_SMP |
303 | register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); | 319 | register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); |
304 | register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction); | 320 | register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction); |
321 | register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction); | ||
305 | #endif | 322 | #endif |
306 | #ifdef CONFIG_PERFMON | 323 | #ifdef CONFIG_PERFMON |
307 | pfm_init_percpu(); | 324 | pfm_init_percpu(); |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 1d7cc7e2ce32..f8ae709de0b5 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1689,7 +1689,7 @@ format_mca_init_stack(void *mca_data, unsigned long offset, | |||
1689 | ti->preempt_count = 1; | 1689 | ti->preempt_count = 1; |
1690 | ti->task = p; | 1690 | ti->task = p; |
1691 | ti->cpu = cpu; | 1691 | ti->cpu = cpu; |
1692 | p->thread_info = ti; | 1692 | p->stack = ti; |
1693 | p->state = TASK_UNINTERRUPTIBLE; | 1693 | p->state = TASK_UNINTERRUPTIBLE; |
1694 | cpu_set(cpu, p->cpus_allowed); | 1694 | cpu_set(cpu, p->cpus_allowed); |
1695 | INIT_LIST_HEAD(&p->tasks); | 1695 | INIT_LIST_HEAD(&p->tasks); |
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index a71df9ae0397..85829e27785c 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c | |||
@@ -975,9 +975,11 @@ static int palinfo_cpu_callback(struct notifier_block *nfb, | |||
975 | 975 | ||
976 | switch (action) { | 976 | switch (action) { |
977 | case CPU_ONLINE: | 977 | case CPU_ONLINE: |
978 | case CPU_ONLINE_FROZEN: | ||
978 | create_palinfo_proc_entries(hotcpu); | 979 | create_palinfo_proc_entries(hotcpu); |
979 | break; | 980 | break; |
980 | case CPU_DEAD: | 981 | case CPU_DEAD: |
982 | case CPU_DEAD_FROZEN: | ||
981 | remove_palinfo_proc_entries(hotcpu); | 983 | remove_palinfo_proc_entries(hotcpu); |
982 | break; | 984 | break; |
983 | } | 985 | } |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 8bb571a8a738..d1c3ed9943e5 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -155,7 +155,7 @@ show_regs (struct pt_regs *regs) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | void | 157 | void |
158 | do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall) | 158 | do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall) |
159 | { | 159 | { |
160 | if (fsys_mode(current, &scr->pt)) { | 160 | if (fsys_mode(current, &scr->pt)) { |
161 | /* defer signal-handling etc. until we return to privilege-level 0. */ | 161 | /* defer signal-handling etc. until we return to privilege-level 0. */ |
@@ -170,8 +170,8 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall | |||
170 | #endif | 170 | #endif |
171 | 171 | ||
172 | /* deal with pending signal delivery */ | 172 | /* deal with pending signal delivery */ |
173 | if (test_thread_flag(TIF_SIGPENDING)) | 173 | if (test_thread_flag(TIF_SIGPENDING)||test_thread_flag(TIF_RESTORE_SIGMASK)) |
174 | ia64_do_signal(oldset, scr, in_syscall); | 174 | ia64_do_signal(scr, in_syscall); |
175 | } | 175 | } |
176 | 176 | ||
177 | static int pal_halt = 1; | 177 | static int pal_halt = 1; |
@@ -236,6 +236,7 @@ void cpu_idle_wait(void) | |||
236 | { | 236 | { |
237 | unsigned int cpu, this_cpu = get_cpu(); | 237 | unsigned int cpu, this_cpu = get_cpu(); |
238 | cpumask_t map; | 238 | cpumask_t map; |
239 | cpumask_t tmp = current->cpus_allowed; | ||
239 | 240 | ||
240 | set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); | 241 | set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); |
241 | put_cpu(); | 242 | put_cpu(); |
@@ -257,6 +258,7 @@ void cpu_idle_wait(void) | |||
257 | } | 258 | } |
258 | cpus_and(map, map, cpu_online_map); | 259 | cpus_and(map, map, cpu_online_map); |
259 | } while (!cpus_empty(map)); | 260 | } while (!cpus_empty(map)); |
261 | set_cpus_allowed(current, tmp); | ||
260 | } | 262 | } |
261 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 263 | EXPORT_SYMBOL_GPL(cpu_idle_wait); |
262 | 264 | ||
diff --git a/arch/ia64/kernel/relocate_kernel.S b/arch/ia64/kernel/relocate_kernel.S index ae473e3f2a0d..903babd22d62 100644 --- a/arch/ia64/kernel/relocate_kernel.S +++ b/arch/ia64/kernel/relocate_kernel.S | |||
@@ -94,7 +94,7 @@ GLOBAL_ENTRY(relocate_new_kernel) | |||
94 | 4: | 94 | 4: |
95 | srlz.i | 95 | srlz.i |
96 | ;; | 96 | ;; |
97 | //purge TR entry for kernel text and data | 97 | // purge TR entry for kernel text and data |
98 | movl r16=KERNEL_START | 98 | movl r16=KERNEL_START |
99 | mov r18=KERNEL_TR_PAGE_SHIFT<<2 | 99 | mov r18=KERNEL_TR_PAGE_SHIFT<<2 |
100 | ;; | 100 | ;; |
@@ -104,15 +104,6 @@ GLOBAL_ENTRY(relocate_new_kernel) | |||
104 | srlz.i | 104 | srlz.i |
105 | ;; | 105 | ;; |
106 | 106 | ||
107 | // purge TR entry for percpu data | ||
108 | movl r16=PERCPU_ADDR | ||
109 | mov r18=PERCPU_PAGE_SHIFT<<2 | ||
110 | ;; | ||
111 | ptr.d r16,r18 | ||
112 | ;; | ||
113 | srlz.d | ||
114 | ;; | ||
115 | |||
116 | // purge TR entry for pal code | 107 | // purge TR entry for pal code |
117 | mov r16=in3 | 108 | mov r16=in3 |
118 | mov r18=IA64_GRANULE_SHIFT<<2 | 109 | mov r18=IA64_GRANULE_SHIFT<<2 |
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index a51f1d0bfb70..89f6b138a62c 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c | |||
@@ -582,6 +582,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu | |||
582 | struct salinfo_data *data; | 582 | struct salinfo_data *data; |
583 | switch (action) { | 583 | switch (action) { |
584 | case CPU_ONLINE: | 584 | case CPU_ONLINE: |
585 | case CPU_ONLINE_FROZEN: | ||
585 | spin_lock_irqsave(&data_saved_lock, flags); | 586 | spin_lock_irqsave(&data_saved_lock, flags); |
586 | for (i = 0, data = salinfo_data; | 587 | for (i = 0, data = salinfo_data; |
587 | i < ARRAY_SIZE(salinfo_data); | 588 | i < ARRAY_SIZE(salinfo_data); |
@@ -592,6 +593,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu | |||
592 | spin_unlock_irqrestore(&data_saved_lock, flags); | 593 | spin_unlock_irqrestore(&data_saved_lock, flags); |
593 | break; | 594 | break; |
594 | case CPU_DEAD: | 595 | case CPU_DEAD: |
596 | case CPU_DEAD_FROZEN: | ||
595 | spin_lock_irqsave(&data_saved_lock, flags); | 597 | spin_lock_irqsave(&data_saved_lock, flags); |
596 | for (i = 0, data = salinfo_data; | 598 | for (i = 0, data = salinfo_data; |
597 | i < ARRAY_SIZE(salinfo_data); | 599 | i < ARRAY_SIZE(salinfo_data); |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 6e19da122ae3..9df1efe7487d 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -786,7 +786,7 @@ identify_cpu (struct cpuinfo_ia64 *c) | |||
786 | c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1)); | 786 | c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1)); |
787 | } | 787 | } |
788 | 788 | ||
789 | void | 789 | void __init |
790 | setup_per_cpu_areas (void) | 790 | setup_per_cpu_areas (void) |
791 | { | 791 | { |
792 | /* start_kernel() requires this... */ | 792 | /* start_kernel() requires this... */ |
diff --git a/arch/ia64/kernel/sigframe.h b/arch/ia64/kernel/sigframe.h index 37b986cb86e0..9fd9a1933b3d 100644 --- a/arch/ia64/kernel/sigframe.h +++ b/arch/ia64/kernel/sigframe.h | |||
@@ -22,4 +22,4 @@ struct sigframe { | |||
22 | struct sigcontext sc; | 22 | struct sigcontext sc; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | extern long ia64_do_signal (sigset_t *, struct sigscratch *, long); | 25 | extern void ia64_do_signal (struct sigscratch *, long); |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 0dcd56da6001..aeec8184e862 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -40,47 +40,6 @@ | |||
40 | # define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0]) | 40 | # define GET_SIGSET(k,u) __get_user((k)->sig[0], &(u)->sig[0]) |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | long | ||
44 | ia64_rt_sigsuspend (sigset_t __user *uset, size_t sigsetsize, struct sigscratch *scr) | ||
45 | { | ||
46 | sigset_t oldset, set; | ||
47 | |||
48 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
49 | if (sigsetsize != sizeof(sigset_t)) | ||
50 | return -EINVAL; | ||
51 | |||
52 | if (!access_ok(VERIFY_READ, uset, sigsetsize)) | ||
53 | return -EFAULT; | ||
54 | |||
55 | if (GET_SIGSET(&set, uset)) | ||
56 | return -EFAULT; | ||
57 | |||
58 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
59 | |||
60 | spin_lock_irq(¤t->sighand->siglock); | ||
61 | { | ||
62 | oldset = current->blocked; | ||
63 | current->blocked = set; | ||
64 | recalc_sigpending(); | ||
65 | } | ||
66 | spin_unlock_irq(¤t->sighand->siglock); | ||
67 | |||
68 | /* | ||
69 | * The return below usually returns to the signal handler. We need to | ||
70 | * pre-set the correct error code here to ensure that the right values | ||
71 | * get saved in sigcontext by ia64_do_signal. | ||
72 | */ | ||
73 | scr->pt.r8 = EINTR; | ||
74 | scr->pt.r10 = -1; | ||
75 | |||
76 | while (1) { | ||
77 | current->state = TASK_INTERRUPTIBLE; | ||
78 | schedule(); | ||
79 | if (ia64_do_signal(&oldset, scr, 1)) | ||
80 | return -EINTR; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | asmlinkage long | 43 | asmlinkage long |
85 | sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2, | 44 | sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2, |
86 | long arg3, long arg4, long arg5, long arg6, long arg7, | 45 | long arg3, long arg4, long arg5, long arg6, long arg7, |
@@ -477,10 +436,11 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse | |||
477 | * Note that `init' is a special process: it doesn't get signals it doesn't want to | 436 | * Note that `init' is a special process: it doesn't get signals it doesn't want to |
478 | * handle. Thus you cannot kill init even with a SIGKILL even by mistake. | 437 | * handle. Thus you cannot kill init even with a SIGKILL even by mistake. |
479 | */ | 438 | */ |
480 | long | 439 | void |
481 | ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) | 440 | ia64_do_signal (struct sigscratch *scr, long in_syscall) |
482 | { | 441 | { |
483 | struct k_sigaction ka; | 442 | struct k_sigaction ka; |
443 | sigset_t *oldset; | ||
484 | siginfo_t info; | 444 | siginfo_t info; |
485 | long restart = in_syscall; | 445 | long restart = in_syscall; |
486 | long errno = scr->pt.r8; | 446 | long errno = scr->pt.r8; |
@@ -492,9 +452,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) | |||
492 | * doing anything if so. | 452 | * doing anything if so. |
493 | */ | 453 | */ |
494 | if (!user_mode(&scr->pt)) | 454 | if (!user_mode(&scr->pt)) |
495 | return 0; | 455 | return; |
496 | 456 | ||
497 | if (!oldset) | 457 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
458 | oldset = ¤t->saved_sigmask; | ||
459 | else | ||
498 | oldset = ¤t->blocked; | 460 | oldset = ¤t->blocked; |
499 | 461 | ||
500 | /* | 462 | /* |
@@ -557,8 +519,15 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) | |||
557 | * Whee! Actually deliver the signal. If the delivery failed, we need to | 519 | * Whee! Actually deliver the signal. If the delivery failed, we need to |
558 | * continue to iterate in this loop so we can deliver the SIGSEGV... | 520 | * continue to iterate in this loop so we can deliver the SIGSEGV... |
559 | */ | 521 | */ |
560 | if (handle_signal(signr, &ka, &info, oldset, scr)) | 522 | if (handle_signal(signr, &ka, &info, oldset, scr)) { |
561 | return 1; | 523 | /* a signal was successfully delivered; the saved |
524 | * sigmask will have been stored in the signal frame, | ||
525 | * and will be restored by sigreturn, so we can simply | ||
526 | * clear the TIF_RESTORE_SIGMASK flag */ | ||
527 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
528 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
529 | return; | ||
530 | } | ||
562 | } | 531 | } |
563 | 532 | ||
564 | /* Did we come from a system call? */ | 533 | /* Did we come from a system call? */ |
@@ -584,5 +553,11 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) | |||
584 | } | 553 | } |
585 | } | 554 | } |
586 | } | 555 | } |
587 | return 0; | 556 | |
557 | /* if there's no signal to deliver, we just put the saved sigmask | ||
558 | * back */ | ||
559 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
560 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
561 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
562 | } | ||
588 | } | 563 | } |
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 55ddd809b02d..221de3804560 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c | |||
@@ -50,6 +50,18 @@ | |||
50 | #include <asm/mca.h> | 50 | #include <asm/mca.h> |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Note: alignment of 4 entries/cacheline was empirically determined | ||
54 | * to be a good tradeoff between hot cachelines & spreading the array | ||
55 | * across too many cacheline. | ||
56 | */ | ||
57 | static struct local_tlb_flush_counts { | ||
58 | unsigned int count; | ||
59 | } __attribute__((__aligned__(32))) local_tlb_flush_counts[NR_CPUS]; | ||
60 | |||
61 | static DEFINE_PER_CPU(unsigned int, shadow_flush_counts[NR_CPUS]) ____cacheline_aligned; | ||
62 | |||
63 | |||
64 | /* | ||
53 | * Structure and data for smp_call_function(). This is designed to minimise static memory | 65 | * Structure and data for smp_call_function(). This is designed to minimise static memory |
54 | * requirements. It also looks cleaner. | 66 | * requirements. It also looks cleaner. |
55 | */ | 67 | */ |
@@ -248,6 +260,62 @@ smp_send_reschedule (int cpu) | |||
248 | platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); | 260 | platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); |
249 | } | 261 | } |
250 | 262 | ||
263 | /* | ||
264 | * Called with preeemption disabled. | ||
265 | */ | ||
266 | static void | ||
267 | smp_send_local_flush_tlb (int cpu) | ||
268 | { | ||
269 | platform_send_ipi(cpu, IA64_IPI_LOCAL_TLB_FLUSH, IA64_IPI_DM_INT, 0); | ||
270 | } | ||
271 | |||
272 | void | ||
273 | smp_local_flush_tlb(void) | ||
274 | { | ||
275 | /* | ||
276 | * Use atomic ops. Otherwise, the load/increment/store sequence from | ||
277 | * a "++" operation can have the line stolen between the load & store. | ||
278 | * The overhead of the atomic op in negligible in this case & offers | ||
279 | * significant benefit for the brief periods where lots of cpus | ||
280 | * are simultaneously flushing TLBs. | ||
281 | */ | ||
282 | ia64_fetchadd(1, &local_tlb_flush_counts[smp_processor_id()].count, acq); | ||
283 | local_flush_tlb_all(); | ||
284 | } | ||
285 | |||
286 | #define FLUSH_DELAY 5 /* Usec backoff to eliminate excessive cacheline bouncing */ | ||
287 | |||
288 | void | ||
289 | smp_flush_tlb_cpumask(cpumask_t xcpumask) | ||
290 | { | ||
291 | unsigned int *counts = __ia64_per_cpu_var(shadow_flush_counts); | ||
292 | cpumask_t cpumask = xcpumask; | ||
293 | int mycpu, cpu, flush_mycpu = 0; | ||
294 | |||
295 | preempt_disable(); | ||
296 | mycpu = smp_processor_id(); | ||
297 | |||
298 | for_each_cpu_mask(cpu, cpumask) | ||
299 | counts[cpu] = local_tlb_flush_counts[cpu].count; | ||
300 | |||
301 | mb(); | ||
302 | for_each_cpu_mask(cpu, cpumask) { | ||
303 | if (cpu == mycpu) | ||
304 | flush_mycpu = 1; | ||
305 | else | ||
306 | smp_send_local_flush_tlb(cpu); | ||
307 | } | ||
308 | |||
309 | if (flush_mycpu) | ||
310 | smp_local_flush_tlb(); | ||
311 | |||
312 | for_each_cpu_mask(cpu, cpumask) | ||
313 | while(counts[cpu] == local_tlb_flush_counts[cpu].count) | ||
314 | udelay(FLUSH_DELAY); | ||
315 | |||
316 | preempt_enable(); | ||
317 | } | ||
318 | |||
251 | void | 319 | void |
252 | smp_flush_tlb_all (void) | 320 | smp_flush_tlb_all (void) |
253 | { | 321 | { |
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 687500ddb4b8..94ae3c87d828 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c | |||
@@ -412,9 +412,11 @@ static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, | |||
412 | sys_dev = get_cpu_sysdev(cpu); | 412 | sys_dev = get_cpu_sysdev(cpu); |
413 | switch (action) { | 413 | switch (action) { |
414 | case CPU_ONLINE: | 414 | case CPU_ONLINE: |
415 | case CPU_ONLINE_FROZEN: | ||
415 | cache_add_dev(sys_dev); | 416 | cache_add_dev(sys_dev); |
416 | break; | 417 | break; |
417 | case CPU_DEAD: | 418 | case CPU_DEAD: |
419 | case CPU_DEAD_FROZEN: | ||
418 | cache_remove_dev(sys_dev); | 420 | cache_remove_dev(sys_dev); |
419 | break; | 421 | break; |
420 | } | 422 | } |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 5bfb8be02b70..b8e0d70bf989 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -43,9 +43,9 @@ die (const char *str, struct pt_regs *regs, long err) | |||
43 | u32 lock_owner; | 43 | u32 lock_owner; |
44 | int lock_owner_depth; | 44 | int lock_owner_depth; |
45 | } die = { | 45 | } die = { |
46 | .lock = SPIN_LOCK_UNLOCKED, | 46 | .lock = __SPIN_LOCK_UNLOCKED(die.lock), |
47 | .lock_owner = -1, | 47 | .lock_owner = -1, |
48 | .lock_owner_depth = 0 | 48 | .lock_owner_depth = 0 |
49 | }; | 49 | }; |
50 | static int die_counter; | 50 | static int die_counter; |
51 | int cpu = get_cpu(); | 51 | int cpu = get_cpu(); |
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index 93d5a3b41f69..fe1426266b9b 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c | |||
@@ -60,6 +60,7 @@ | |||
60 | # define UNW_DEBUG_ON(n) unw_debug_level >= n | 60 | # define UNW_DEBUG_ON(n) unw_debug_level >= n |
61 | /* Do not code a printk level, not all debug lines end in newline */ | 61 | /* Do not code a printk level, not all debug lines end in newline */ |
62 | # define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__) | 62 | # define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__) |
63 | # undef inline | ||
63 | # define inline | 64 | # define inline |
64 | #else /* !UNW_DEBUG */ | 65 | #else /* !UNW_DEBUG */ |
65 | # define UNW_DEBUG_ON(n) 0 | 66 | # define UNW_DEBUG_ON(n) 0 |
@@ -145,7 +146,7 @@ static struct { | |||
145 | # endif | 146 | # endif |
146 | } unw = { | 147 | } unw = { |
147 | .tables = &unw.kernel_table, | 148 | .tables = &unw.kernel_table, |
148 | .lock = SPIN_LOCK_UNLOCKED, | 149 | .lock = __SPIN_LOCK_UNLOCKED(unw.lock), |
149 | .save_order = { | 150 | .save_order = { |
150 | UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, | 151 | UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, |
151 | UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR | 152 | UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR |
@@ -1943,9 +1944,9 @@ EXPORT_SYMBOL(unw_unwind); | |||
1943 | int | 1944 | int |
1944 | unw_unwind_to_user (struct unw_frame_info *info) | 1945 | unw_unwind_to_user (struct unw_frame_info *info) |
1945 | { | 1946 | { |
1946 | unsigned long ip, sp, pr = 0; | 1947 | unsigned long ip, sp, pr = info->pr; |
1947 | 1948 | ||
1948 | while (unw_unwind(info) >= 0) { | 1949 | do { |
1949 | unw_get_sp(info, &sp); | 1950 | unw_get_sp(info, &sp); |
1950 | if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp) | 1951 | if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp) |
1951 | < IA64_PT_REGS_SIZE) { | 1952 | < IA64_PT_REGS_SIZE) { |
@@ -1963,7 +1964,7 @@ unw_unwind_to_user (struct unw_frame_info *info) | |||
1963 | __FUNCTION__, ip); | 1964 | __FUNCTION__, ip); |
1964 | return -1; | 1965 | return -1; |
1965 | } | 1966 | } |
1966 | } | 1967 | } while (unw_unwind(info) >= 0); |
1967 | unw_get_ip(info, &ip); | 1968 | unw_get_ip(info, &ip); |
1968 | UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", | 1969 | UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", |
1969 | __FUNCTION__, ip); | 1970 | __FUNCTION__, ip); |
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index ffad7624436c..fa4e6d4810f3 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c | |||
@@ -32,9 +32,9 @@ static struct { | |||
32 | } purge; | 32 | } purge; |
33 | 33 | ||
34 | struct ia64_ctx ia64_ctx = { | 34 | struct ia64_ctx ia64_ctx = { |
35 | .lock = SPIN_LOCK_UNLOCKED, | 35 | .lock = __SPIN_LOCK_UNLOCKED(ia64_ctx.lock), |
36 | .next = 1, | 36 | .next = 1, |
37 | .max_ctx = ~0U | 37 | .max_ctx = ~0U |
38 | }; | 38 | }; |
39 | 39 | ||
40 | DEFINE_PER_CPU(u8, ia64_need_tlb_flush); | 40 | DEFINE_PER_CPU(u8, ia64_need_tlb_flush); |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 8d2a1bfbfe7c..7f6d2360a262 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
@@ -59,6 +59,22 @@ void sn_intr_free(nasid_t local_nasid, int local_widget, | |||
59 | (u64) sn_irq_info->irq_cookie, 0, 0); | 59 | (u64) sn_irq_info->irq_cookie, 0, 0); |
60 | } | 60 | } |
61 | 61 | ||
62 | u64 sn_intr_redirect(nasid_t local_nasid, int local_widget, | ||
63 | struct sn_irq_info *sn_irq_info, | ||
64 | nasid_t req_nasid, int req_slice) | ||
65 | { | ||
66 | struct ia64_sal_retval ret_stuff; | ||
67 | ret_stuff.status = 0; | ||
68 | ret_stuff.v0 = 0; | ||
69 | |||
70 | SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, | ||
71 | (u64) SAL_INTR_REDIRECT, (u64) local_nasid, | ||
72 | (u64) local_widget, __pa(sn_irq_info), | ||
73 | (u64) req_nasid, (u64) req_slice, 0); | ||
74 | |||
75 | return ret_stuff.status; | ||
76 | } | ||
77 | |||
62 | static unsigned int sn_startup_irq(unsigned int irq) | 78 | static unsigned int sn_startup_irq(unsigned int irq) |
63 | { | 79 | { |
64 | return 0; | 80 | return 0; |
@@ -127,15 +143,8 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, | |||
127 | struct sn_irq_info *new_irq_info; | 143 | struct sn_irq_info *new_irq_info; |
128 | struct sn_pcibus_provider *pci_provider; | 144 | struct sn_pcibus_provider *pci_provider; |
129 | 145 | ||
130 | new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); | 146 | bridge = (u64) sn_irq_info->irq_bridge; |
131 | if (new_irq_info == NULL) | ||
132 | return NULL; | ||
133 | |||
134 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); | ||
135 | |||
136 | bridge = (u64) new_irq_info->irq_bridge; | ||
137 | if (!bridge) { | 147 | if (!bridge) { |
138 | kfree(new_irq_info); | ||
139 | return NULL; /* irq is not a device interrupt */ | 148 | return NULL; /* irq is not a device interrupt */ |
140 | } | 149 | } |
141 | 150 | ||
@@ -145,8 +154,25 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, | |||
145 | local_widget = TIO_SWIN_WIDGETNUM(bridge); | 154 | local_widget = TIO_SWIN_WIDGETNUM(bridge); |
146 | else | 155 | else |
147 | local_widget = SWIN_WIDGETNUM(bridge); | 156 | local_widget = SWIN_WIDGETNUM(bridge); |
148 | |||
149 | vector = sn_irq_info->irq_irq; | 157 | vector = sn_irq_info->irq_irq; |
158 | |||
159 | /* Make use of SAL_INTR_REDIRECT if PROM supports it */ | ||
160 | status = sn_intr_redirect(local_nasid, local_widget, sn_irq_info, nasid, slice); | ||
161 | if (!status) { | ||
162 | new_irq_info = sn_irq_info; | ||
163 | goto finish_up; | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * PROM does not support SAL_INTR_REDIRECT, or it failed. | ||
168 | * Revert to old method. | ||
169 | */ | ||
170 | new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); | ||
171 | if (new_irq_info == NULL) | ||
172 | return NULL; | ||
173 | |||
174 | memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); | ||
175 | |||
150 | /* Free the old PROM new_irq_info structure */ | 176 | /* Free the old PROM new_irq_info structure */ |
151 | sn_intr_free(local_nasid, local_widget, new_irq_info); | 177 | sn_intr_free(local_nasid, local_widget, new_irq_info); |
152 | unregister_intr_pda(new_irq_info); | 178 | unregister_intr_pda(new_irq_info); |
@@ -162,11 +188,18 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, | |||
162 | return NULL; | 188 | return NULL; |
163 | } | 189 | } |
164 | 190 | ||
191 | register_intr_pda(new_irq_info); | ||
192 | spin_lock(&sn_irq_info_lock); | ||
193 | list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); | ||
194 | spin_unlock(&sn_irq_info_lock); | ||
195 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); | ||
196 | |||
197 | |||
198 | finish_up: | ||
165 | /* Update kernels new_irq_info with new target info */ | 199 | /* Update kernels new_irq_info with new target info */ |
166 | cpuid = nasid_slice_to_cpuid(new_irq_info->irq_nasid, | 200 | cpuid = nasid_slice_to_cpuid(new_irq_info->irq_nasid, |
167 | new_irq_info->irq_slice); | 201 | new_irq_info->irq_slice); |
168 | new_irq_info->irq_cpuid = cpuid; | 202 | new_irq_info->irq_cpuid = cpuid; |
169 | register_intr_pda(new_irq_info); | ||
170 | 203 | ||
171 | pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; | 204 | pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; |
172 | 205 | ||
@@ -178,11 +211,6 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, | |||
178 | pci_provider && pci_provider->target_interrupt) | 211 | pci_provider && pci_provider->target_interrupt) |
179 | (pci_provider->target_interrupt)(new_irq_info); | 212 | (pci_provider->target_interrupt)(new_irq_info); |
180 | 213 | ||
181 | spin_lock(&sn_irq_info_lock); | ||
182 | list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); | ||
183 | spin_unlock(&sn_irq_info_lock); | ||
184 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); | ||
185 | |||
186 | #ifdef CONFIG_SMP | 214 | #ifdef CONFIG_SMP |
187 | cpuphys = cpu_physical_id(cpuid); | 215 | cpuphys = cpu_physical_id(cpuid); |
188 | set_irq_affinity_info((vector & 0xff), cpuphys, 0); | 216 | set_irq_affinity_info((vector & 0xff), cpuphys, 0); |
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 601747b1e22a..5d318b579fb1 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c | |||
@@ -46,6 +46,9 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats); | |||
46 | 46 | ||
47 | static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); | 47 | static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); |
48 | 48 | ||
49 | /* 0 = old algorithm (no IPI flushes), 1 = ipi deadlock flush, 2 = ipi instead of SHUB ptc, >2 = always ipi */ | ||
50 | static int sn2_flush_opt = 0; | ||
51 | |||
49 | extern unsigned long | 52 | extern unsigned long |
50 | sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, | 53 | sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, |
51 | volatile unsigned long *, unsigned long, | 54 | volatile unsigned long *, unsigned long, |
@@ -76,6 +79,8 @@ struct ptc_stats { | |||
76 | unsigned long shub_itc_clocks; | 79 | unsigned long shub_itc_clocks; |
77 | unsigned long shub_itc_clocks_max; | 80 | unsigned long shub_itc_clocks_max; |
78 | unsigned long shub_ptc_flushes_not_my_mm; | 81 | unsigned long shub_ptc_flushes_not_my_mm; |
82 | unsigned long shub_ipi_flushes; | ||
83 | unsigned long shub_ipi_flushes_itc_clocks; | ||
79 | }; | 84 | }; |
80 | 85 | ||
81 | #define sn2_ptctest 0 | 86 | #define sn2_ptctest 0 |
@@ -121,6 +126,18 @@ void sn_tlb_migrate_finish(struct mm_struct *mm) | |||
121 | flush_tlb_mm(mm); | 126 | flush_tlb_mm(mm); |
122 | } | 127 | } |
123 | 128 | ||
129 | static void | ||
130 | sn2_ipi_flush_all_tlb(struct mm_struct *mm) | ||
131 | { | ||
132 | unsigned long itc; | ||
133 | |||
134 | itc = ia64_get_itc(); | ||
135 | smp_flush_tlb_cpumask(mm->cpu_vm_mask); | ||
136 | itc = ia64_get_itc() - itc; | ||
137 | __get_cpu_var(ptcstats).shub_ipi_flushes_itc_clocks += itc; | ||
138 | __get_cpu_var(ptcstats).shub_ipi_flushes++; | ||
139 | } | ||
140 | |||
124 | /** | 141 | /** |
125 | * sn2_global_tlb_purge - globally purge translation cache of virtual address range | 142 | * sn2_global_tlb_purge - globally purge translation cache of virtual address range |
126 | * @mm: mm_struct containing virtual address range | 143 | * @mm: mm_struct containing virtual address range |
@@ -154,7 +171,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
154 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0; | 171 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0; |
155 | short nasids[MAX_NUMNODES], nix; | 172 | short nasids[MAX_NUMNODES], nix; |
156 | nodemask_t nodes_flushed; | 173 | nodemask_t nodes_flushed; |
157 | int active, max_active, deadlock; | 174 | int active, max_active, deadlock, flush_opt = sn2_flush_opt; |
175 | |||
176 | if (flush_opt > 2) { | ||
177 | sn2_ipi_flush_all_tlb(mm); | ||
178 | return; | ||
179 | } | ||
158 | 180 | ||
159 | nodes_clear(nodes_flushed); | 181 | nodes_clear(nodes_flushed); |
160 | i = 0; | 182 | i = 0; |
@@ -189,6 +211,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
189 | return; | 211 | return; |
190 | } | 212 | } |
191 | 213 | ||
214 | if (flush_opt == 2) { | ||
215 | sn2_ipi_flush_all_tlb(mm); | ||
216 | preempt_enable(); | ||
217 | return; | ||
218 | } | ||
219 | |||
192 | itc = ia64_get_itc(); | 220 | itc = ia64_get_itc(); |
193 | nix = 0; | 221 | nix = 0; |
194 | for_each_node_mask(cnode, nodes_flushed) | 222 | for_each_node_mask(cnode, nodes_flushed) |
@@ -256,6 +284,8 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
256 | } | 284 | } |
257 | if (active >= max_active || i == (nix - 1)) { | 285 | if (active >= max_active || i == (nix - 1)) { |
258 | if ((deadlock = wait_piowc())) { | 286 | if ((deadlock = wait_piowc())) { |
287 | if (flush_opt == 1) | ||
288 | goto done; | ||
259 | sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1); | 289 | sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1); |
260 | if (reset_max_active_on_deadlock()) | 290 | if (reset_max_active_on_deadlock()) |
261 | max_active = 1; | 291 | max_active = 1; |
@@ -267,6 +297,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
267 | start += (1UL << nbits); | 297 | start += (1UL << nbits); |
268 | } while (start < end); | 298 | } while (start < end); |
269 | 299 | ||
300 | done: | ||
270 | itc2 = ia64_get_itc() - itc2; | 301 | itc2 = ia64_get_itc() - itc2; |
271 | __get_cpu_var(ptcstats).shub_itc_clocks += itc2; | 302 | __get_cpu_var(ptcstats).shub_itc_clocks += itc2; |
272 | if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) | 303 | if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) |
@@ -279,6 +310,11 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
279 | 310 | ||
280 | spin_unlock_irqrestore(PTC_LOCK(shub1), flags); | 311 | spin_unlock_irqrestore(PTC_LOCK(shub1), flags); |
281 | 312 | ||
313 | if (flush_opt == 1 && deadlock) { | ||
314 | __get_cpu_var(ptcstats).deadlocks++; | ||
315 | sn2_ipi_flush_all_tlb(mm); | ||
316 | } | ||
317 | |||
282 | preempt_enable(); | 318 | preempt_enable(); |
283 | } | 319 | } |
284 | 320 | ||
@@ -425,24 +461,42 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data) | |||
425 | 461 | ||
426 | if (!cpu) { | 462 | if (!cpu) { |
427 | seq_printf(file, | 463 | seq_printf(file, |
428 | "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2\n"); | 464 | "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2 ipi_fluches ipi_nsec\n"); |
429 | seq_printf(file, "# ptctest %d\n", sn2_ptctest); | 465 | seq_printf(file, "# ptctest %d, flushopt %d\n", sn2_ptctest, sn2_flush_opt); |
430 | } | 466 | } |
431 | 467 | ||
432 | if (cpu < NR_CPUS && cpu_online(cpu)) { | 468 | if (cpu < NR_CPUS && cpu_online(cpu)) { |
433 | stat = &per_cpu(ptcstats, cpu); | 469 | stat = &per_cpu(ptcstats, cpu); |
434 | seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, | 470 | seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, |
435 | stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, | 471 | stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, |
436 | stat->deadlocks, | 472 | stat->deadlocks, |
437 | 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, | 473 | 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, |
438 | 1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, | 474 | 1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, |
439 | 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec, | 475 | 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec, |
440 | stat->shub_ptc_flushes_not_my_mm, | 476 | stat->shub_ptc_flushes_not_my_mm, |
441 | stat->deadlocks2); | 477 | stat->deadlocks2, |
478 | stat->shub_ipi_flushes, | ||
479 | 1000 * stat->shub_ipi_flushes_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec); | ||
442 | } | 480 | } |
443 | return 0; | 481 | return 0; |
444 | } | 482 | } |
445 | 483 | ||
484 | static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, size_t count, loff_t *data) | ||
485 | { | ||
486 | int cpu; | ||
487 | char optstr[64]; | ||
488 | |||
489 | if (copy_from_user(optstr, user, count)) | ||
490 | return -EFAULT; | ||
491 | optstr[count - 1] = '\0'; | ||
492 | sn2_flush_opt = simple_strtoul(optstr, NULL, 0); | ||
493 | |||
494 | for_each_online_cpu(cpu) | ||
495 | memset(&per_cpu(ptcstats, cpu), 0, sizeof(struct ptc_stats)); | ||
496 | |||
497 | return count; | ||
498 | } | ||
499 | |||
446 | static struct seq_operations sn2_ptc_seq_ops = { | 500 | static struct seq_operations sn2_ptc_seq_ops = { |
447 | .start = sn2_ptc_seq_start, | 501 | .start = sn2_ptc_seq_start, |
448 | .next = sn2_ptc_seq_next, | 502 | .next = sn2_ptc_seq_next, |
@@ -458,6 +512,7 @@ static int sn2_ptc_proc_open(struct inode *inode, struct file *file) | |||
458 | static const struct file_operations proc_sn2_ptc_operations = { | 512 | static const struct file_operations proc_sn2_ptc_operations = { |
459 | .open = sn2_ptc_proc_open, | 513 | .open = sn2_ptc_proc_open, |
460 | .read = seq_read, | 514 | .read = seq_read, |
515 | .write = sn2_ptc_proc_write, | ||
461 | .llseek = seq_lseek, | 516 | .llseek = seq_lseek, |
462 | .release = seq_release, | 517 | .release = seq_release, |
463 | }; | 518 | }; |
diff --git a/arch/m68knommu/Kconfig.debug b/arch/m68knommu/Kconfig.debug index 763c9aa0b4fd..9ff47bd09aee 100644 --- a/arch/m68knommu/Kconfig.debug +++ b/arch/m68knommu/Kconfig.debug | |||
@@ -5,7 +5,7 @@ source "lib/Kconfig.debug" | |||
5 | config FULLDEBUG | 5 | config FULLDEBUG |
6 | bool "Full Symbolic/Source Debugging support" | 6 | bool "Full Symbolic/Source Debugging support" |
7 | help | 7 | help |
8 | Enable debuging symbols on kernel build. | 8 | Enable debugging symbols on kernel build. |
9 | 9 | ||
10 | config HIGHPROFILE | 10 | config HIGHPROFILE |
11 | bool "Use fast second timer for profiling" | 11 | bool "Use fast second timer for profiling" |
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c index b988c7bdc6e4..7cd183d346ef 100644 --- a/arch/m68knommu/kernel/asm-offsets.c +++ b/arch/m68knommu/kernel/asm-offsets.c | |||
@@ -31,7 +31,7 @@ int main(void) | |||
31 | DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); | 31 | DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); |
32 | DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); | 32 | DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); |
33 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); | 33 | DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); |
34 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info)); | 34 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack)); |
35 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); | 35 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); |
36 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); | 36 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); |
37 | 37 | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index b7cb048bc771..16ecea3c0813 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -956,7 +956,7 @@ choice | |||
956 | byte order. These modes require different kernels and a different | 956 | byte order. These modes require different kernels and a different |
957 | Linux distribution. In general there is one preferred byteorder for a | 957 | Linux distribution. In general there is one preferred byteorder for a |
958 | particular system but some systems are just as commonly used in the | 958 | particular system but some systems are just as commonly used in the |
959 | one or the other endianess. | 959 | one or the other endianness. |
960 | 960 | ||
961 | config CPU_BIG_ENDIAN | 961 | config CPU_BIG_ENDIAN |
962 | bool "Big endian" | 962 | bool "Big endian" |
@@ -1750,7 +1750,7 @@ config ARCH_DISCONTIGMEM_ENABLE | |||
1750 | bool | 1750 | bool |
1751 | default y if SGI_IP27 | 1751 | default y if SGI_IP27 |
1752 | help | 1752 | help |
1753 | Say Y to upport efficient handling of discontiguous physical memory, | 1753 | Say Y to support efficient handling of discontiguous physical memory, |
1754 | for architectures which are either NUMA (Non-Uniform Memory Access) | 1754 | for architectures which are either NUMA (Non-Uniform Memory Access) |
1755 | or have huge holes in the physical address space for other reasons. | 1755 | or have huge holes in the physical address space for other reasons. |
1756 | See <file:Documentation/vm/numa> for more. | 1756 | See <file:Documentation/vm/numa> for more. |
@@ -1938,7 +1938,7 @@ config KEXEC | |||
1938 | help | 1938 | help |
1939 | kexec is a system call that implements the ability to shutdown your | 1939 | kexec is a system call that implements the ability to shutdown your |
1940 | current kernel, and to start another kernel. It is like a reboot | 1940 | current kernel, and to start another kernel. It is like a reboot |
1941 | but it is indepedent of the system firmware. And like a reboot | 1941 | but it is independent of the system firmware. And like a reboot |
1942 | you can start any kernel with it, not just Linux. | 1942 | you can start any kernel with it, not just Linux. |
1943 | 1943 | ||
1944 | The name comes from the similiarity to the exec system call. | 1944 | The name comes from the similiarity to the exec system call. |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index f2f742df32c7..4892db88a86a 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -92,7 +92,7 @@ cflags-y += -ffreestanding | |||
92 | # when fed the toolchain default! | 92 | # when fed the toolchain default! |
93 | # | 93 | # |
94 | # Certain gcc versions upto gcc 4.1.1 (probably 4.2-subversion as of | 94 | # Certain gcc versions upto gcc 4.1.1 (probably 4.2-subversion as of |
95 | # 2006-10-10 don't properly change the the predefined symbols if -EB / -EL | 95 | # 2006-10-10 don't properly change the predefined symbols if -EB / -EL |
96 | # are used, so we kludge that here. A bug has been filed at | 96 | # are used, so we kludge that here. A bug has been filed at |
97 | # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413. | 97 | # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413. |
98 | # | 98 | # |
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 761a779d5c4f..3b27309d54b1 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -82,7 +82,7 @@ void output_task_defines(void) | |||
82 | { | 82 | { |
83 | text("/* MIPS task_struct offsets. */"); | 83 | text("/* MIPS task_struct offsets. */"); |
84 | offset("#define TASK_STATE ", struct task_struct, state); | 84 | offset("#define TASK_STATE ", struct task_struct, state); |
85 | offset("#define TASK_THREAD_INFO ", struct task_struct, thread_info); | 85 | offset("#define TASK_THREAD_INFO ", struct task_struct, stack); |
86 | offset("#define TASK_FLAGS ", struct task_struct, flags); | 86 | offset("#define TASK_FLAGS ", struct task_struct, flags); |
87 | offset("#define TASK_MM ", struct task_struct, mm); | 87 | offset("#define TASK_MM ", struct task_struct, mm); |
88 | offset("#define TASK_PID ", struct task_struct, pid); | 88 | offset("#define TASK_PID ", struct task_struct, pid); |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 5dcfab6b288e..b361edb83dc6 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -560,7 +560,7 @@ void smtc_boot_secondary(int cpu, struct task_struct *idle) | |||
560 | write_tc_gpr_sp(__KSTK_TOS(idle)); | 560 | write_tc_gpr_sp(__KSTK_TOS(idle)); |
561 | 561 | ||
562 | /* global pointer */ | 562 | /* global pointer */ |
563 | write_tc_gpr_gp((unsigned long)idle->thread_info); | 563 | write_tc_gpr_gp((unsigned long)task_thread_info(idle)); |
564 | 564 | ||
565 | smtc_status |= SMTC_MTC_ACTIVE; | 565 | smtc_status |= SMTC_MTC_ACTIVE; |
566 | write_tc_c0_tchalt(0); | 566 | write_tc_c0_tchalt(0); |
diff --git a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c index 7a7444874e80..0ad39e53f7b1 100644 --- a/arch/mips/pci/fixup-sb1250.c +++ b/arch/mips/pci/fixup-sb1250.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | 15 | ||
16 | /* | 16 | /* |
17 | * Set the the BCM1250, etc. PCI host bridge's TRDY timeout | 17 | * Set the BCM1250, etc. PCI host bridge's TRDY timeout |
18 | * to the finite max. | 18 | * to the finite max. |
19 | */ | 19 | */ |
20 | static void __init quirk_sb1250_pci(struct pci_dev *dev) | 20 | static void __init quirk_sb1250_pci(struct pci_dev *dev) |
@@ -35,7 +35,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT, | |||
35 | quirk_sb1250_ht); | 35 | quirk_sb1250_ht); |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Set the the SP1011 HT/PCI bridge's TRDY timeout to the finite max. | 38 | * Set the SP1011 HT/PCI bridge's TRDY timeout to the finite max. |
39 | */ | 39 | */ |
40 | static void __init quirk_sp1011(struct pci_dev *dev) | 40 | static void __init quirk_sp1011(struct pci_dev *dev) |
41 | { | 41 | { |
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index 54fdb959149c..d3b7917a87cb 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c | |||
@@ -54,7 +54,7 @@ | |||
54 | 54 | ||
55 | int main(void) | 55 | int main(void) |
56 | { | 56 | { |
57 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info)); | 57 | DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack)); |
58 | DEFINE(TASK_STATE, offsetof(struct task_struct, state)); | 58 | DEFINE(TASK_STATE, offsetof(struct task_struct, state)); |
59 | DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); | 59 | DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); |
60 | DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending)); | 60 | DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending)); |
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index f70e795c262e..346cd3befe1e 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug | |||
@@ -32,7 +32,7 @@ config HCALL_STATS | |||
32 | depends on PPC_PSERIES && DEBUG_FS | 32 | depends on PPC_PSERIES && DEBUG_FS |
33 | help | 33 | help |
34 | Adds code to keep track of the number of hypervisor calls made and | 34 | Adds code to keep track of the number of hypervisor calls made and |
35 | the amount of time spent in hypervisor callsr. Wall time spent in | 35 | the amount of time spent in hypervisor calls. Wall time spent in |
36 | each call is always calculated, and if available CPU cycles spent | 36 | each call is always calculated, and if available CPU cycles spent |
37 | are also calculated. A directory named hcall_inst is added at the | 37 | are also calculated. A directory named hcall_inst is added at the |
38 | root of the debugfs filesystem. Within the hcall_inst directory | 38 | root of the debugfs filesystem. Within the hcall_inst directory |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index d6803fb7b28b..2cb1d9487796 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -58,7 +58,7 @@ int main(void) | |||
58 | #ifdef CONFIG_PPC64 | 58 | #ifdef CONFIG_PPC64 |
59 | DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); | 59 | DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); |
60 | #else | 60 | #else |
61 | DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info)); | 61 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); |
62 | DEFINE(PTRACE, offsetof(struct task_struct, ptrace)); | 62 | DEFINE(PTRACE, offsetof(struct task_struct, ptrace)); |
63 | #endif /* CONFIG_PPC64 */ | 63 | #endif /* CONFIG_PPC64 */ |
64 | 64 | ||
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index cae39d9dfe48..68991c2d4a1b 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -342,10 +342,12 @@ static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, | |||
342 | 342 | ||
343 | switch (action) { | 343 | switch (action) { |
344 | case CPU_ONLINE: | 344 | case CPU_ONLINE: |
345 | case CPU_ONLINE_FROZEN: | ||
345 | register_cpu_online(cpu); | 346 | register_cpu_online(cpu); |
346 | break; | 347 | break; |
347 | #ifdef CONFIG_HOTPLUG_CPU | 348 | #ifdef CONFIG_HOTPLUG_CPU |
348 | case CPU_DEAD: | 349 | case CPU_DEAD: |
350 | case CPU_DEAD_FROZEN: | ||
349 | unregister_cpu_online(cpu); | 351 | unregister_cpu_online(cpu); |
350 | break; | 352 | break; |
351 | #endif | 353 | #endif |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index b3a592b25ab3..de45aa82d97b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -252,12 +252,15 @@ static int __cpuinit cpu_numa_callback(struct notifier_block *nfb, | |||
252 | 252 | ||
253 | switch (action) { | 253 | switch (action) { |
254 | case CPU_UP_PREPARE: | 254 | case CPU_UP_PREPARE: |
255 | case CPU_UP_PREPARE_FROZEN: | ||
255 | numa_setup_cpu(lcpu); | 256 | numa_setup_cpu(lcpu); |
256 | ret = NOTIFY_OK; | 257 | ret = NOTIFY_OK; |
257 | break; | 258 | break; |
258 | #ifdef CONFIG_HOTPLUG_CPU | 259 | #ifdef CONFIG_HOTPLUG_CPU |
259 | case CPU_DEAD: | 260 | case CPU_DEAD: |
261 | case CPU_DEAD_FROZEN: | ||
260 | case CPU_UP_CANCELED: | 262 | case CPU_UP_CANCELED: |
263 | case CPU_UP_CANCELED_FROZEN: | ||
261 | unmap_cpu_from_node(lcpu); | 264 | unmap_cpu_from_node(lcpu); |
262 | break; | 265 | break; |
263 | ret = NOTIFY_OK; | 266 | ret = NOTIFY_OK; |
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 626b29f38304..c29293befba9 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c | |||
@@ -747,7 +747,7 @@ cell_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) | |||
747 | * counter value etc.) are not copied to the actual registers | 747 | * counter value etc.) are not copied to the actual registers |
748 | * until the performance monitor is enabled. In order to get | 748 | * until the performance monitor is enabled. In order to get |
749 | * this to work as desired, the permormance monitor needs to | 749 | * this to work as desired, the permormance monitor needs to |
750 | * be disabled while writting to the latches. This is a | 750 | * be disabled while writing to the latches. This is a |
751 | * HW design issue. | 751 | * HW design issue. |
752 | */ | 752 | */ |
753 | cbe_enable_pm(cpu); | 753 | cbe_enable_pm(cpu); |
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c index a35315af5c53..cf0e7bc8c2e7 100644 --- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /*arch/ppc/platforms/mpc86xads-setup.c | 1 | /*arch/powerpc/platforms/8xx/mpc86xads_setup.c |
2 | * | 2 | * |
3 | * Platform setup for the Freescale mpc86xads board | 3 | * Platform setup for the Freescale mpc86xads board |
4 | * | 4 | * |
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c index a57b57785acd..c36e475d93dc 100644 --- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c +++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /*arch/ppc/platforms/mpc885ads-setup.c | 1 | /*arch/powerpc/platforms/8xx/mpc885ads_setup.c |
2 | * | 2 | * |
3 | * Platform setup for the Freescale mpc885ads board | 3 | * Platform setup for the Freescale mpc885ads board |
4 | * | 4 | * |
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c index d68d920eb2c4..7fb92f23f380 100644 --- a/arch/powerpc/platforms/cell/io-workarounds.c +++ b/arch/powerpc/platforms/cell/io-workarounds.c | |||
@@ -74,7 +74,7 @@ static void spider_io_flush(const volatile void __iomem *addr) | |||
74 | /* Fast path if we have a non-0 token, it indicates which bus we | 74 | /* Fast path if we have a non-0 token, it indicates which bus we |
75 | * are on. | 75 | * are on. |
76 | * | 76 | * |
77 | * If the token is 0, that means either the the ioremap was done | 77 | * If the token is 0, that means either that the ioremap was done |
78 | * before we initialized this layer, or it's a PIO operation. We | 78 | * before we initialized this layer, or it's a PIO operation. We |
79 | * fallback to a low path in this case. Hopefully, internal devices | 79 | * fallback to a low path in this case. Hopefully, internal devices |
80 | * which are ioremap'ed early should use in_XX/out_XX functions | 80 | * which are ioremap'ed early should use in_XX/out_XX functions |
diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c index c5850a272650..e8e94321b59e 100644 --- a/arch/ppc/kernel/asm-offsets.c +++ b/arch/ppc/kernel/asm-offsets.c | |||
@@ -35,7 +35,7 @@ int | |||
35 | main(void) | 35 | main(void) |
36 | { | 36 | { |
37 | DEFINE(THREAD, offsetof(struct task_struct, thread)); | 37 | DEFINE(THREAD, offsetof(struct task_struct, thread)); |
38 | DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info)); | 38 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); |
39 | DEFINE(MM, offsetof(struct task_struct, mm)); | 39 | DEFINE(MM, offsetof(struct task_struct, mm)); |
40 | DEFINE(PTRACE, offsetof(struct task_struct, ptrace)); | 40 | DEFINE(PTRACE, offsetof(struct task_struct, ptrace)); |
41 | DEFINE(KSP, offsetof(struct thread_struct, ksp)); | 41 | DEFINE(KSP, offsetof(struct thread_struct, ksp)); |
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c index 7ce5364fdb3b..bf72204125c5 100644 --- a/arch/ppc/platforms/mpc866ads_setup.c +++ b/arch/ppc/platforms/mpc866ads_setup.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /*arch/ppc/platforms/mpc866ads-setup.c | 1 | /*arch/ppc/platforms/mpc866ads_setup.c |
2 | * | 2 | * |
3 | * Platform setup for the Freescale mpc866ads board | 3 | * Platform setup for the Freescale mpc866ads board |
4 | * | 4 | * |
diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c index 10659c24b1be..9192777d0f78 100644 --- a/arch/ppc/syslib/ipic.c +++ b/arch/ppc/syslib/ipic.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * include/asm-ppc/ipic.c | 2 | * arch/ppc/syslib/ipic.c |
3 | * | 3 | * |
4 | * IPIC routines implementations. | 4 | * IPIC routines implementations. |
5 | * | 5 | * |
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index ee89b33145d5..81a2b92ab0c2 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -567,9 +567,11 @@ appldata_cpu_notify(struct notifier_block *self, | |||
567 | { | 567 | { |
568 | switch (action) { | 568 | switch (action) { |
569 | case CPU_ONLINE: | 569 | case CPU_ONLINE: |
570 | case CPU_ONLINE_FROZEN: | ||
570 | appldata_online_cpu((long) hcpu); | 571 | appldata_online_cpu((long) hcpu); |
571 | break; | 572 | break; |
572 | case CPU_DEAD: | 573 | case CPU_DEAD: |
574 | case CPU_DEAD_FROZEN: | ||
573 | appldata_offline_cpu((long) hcpu); | 575 | appldata_offline_cpu((long) hcpu); |
574 | break; | 576 | break; |
575 | default: | 577 | default: |
diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig index 99ff9f08e4d7..d1defbbfcd81 100644 --- a/arch/s390/crypto/Kconfig +++ b/arch/s390/crypto/Kconfig | |||
@@ -54,7 +54,7 @@ config S390_PRNG | |||
54 | default "m" | 54 | default "m" |
55 | help | 55 | help |
56 | Select this option if you want to use the s390 pseudo random number | 56 | Select this option if you want to use the s390 pseudo random number |
57 | generator. The PRNG is part of the cryptograhic processor functions | 57 | generator. The PRNG is part of the cryptographic processor functions |
58 | and uses triple-DES to generate secure random numbers like the | 58 | and uses triple-DES to generate secure random numbers like the |
59 | ANSI X9.17 standard. The PRNG is usable via the char device | 59 | ANSI X9.17 standard. The PRNG is usable via the char device |
60 | /dev/prandom. | 60 | /dev/prandom. |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index ec514fe5ccd0..1375f8a4469e 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | int main(void) | 16 | int main(void) |
17 | { | 17 | { |
18 | DEFINE(__THREAD_info, offsetof(struct task_struct, thread_info),); | 18 | DEFINE(__THREAD_info, offsetof(struct task_struct, stack),); |
19 | DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp),); | 19 | DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp),); |
20 | DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info),); | 20 | DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info),); |
21 | DEFINE(__THREAD_mm_segment, | 21 | DEFINE(__THREAD_mm_segment, |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b7977027a28f..09f028a3266b 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -789,10 +789,12 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self, | |||
789 | 789 | ||
790 | switch (action) { | 790 | switch (action) { |
791 | case CPU_ONLINE: | 791 | case CPU_ONLINE: |
792 | case CPU_ONLINE_FROZEN: | ||
792 | if (sysdev_create_file(s, &attr_capability)) | 793 | if (sysdev_create_file(s, &attr_capability)) |
793 | return NOTIFY_BAD; | 794 | return NOTIFY_BAD; |
794 | break; | 795 | break; |
795 | case CPU_DEAD: | 796 | case CPU_DEAD: |
797 | case CPU_DEAD_FROZEN: | ||
796 | sysdev_remove_file(s, &attr_capability); | 798 | sysdev_remove_file(s, &attr_capability); |
797 | break; | 799 | break; |
798 | } | 800 | } |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index d74eb120a9c6..038179ecf6a9 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -52,6 +52,9 @@ config GENERIC_IOMAP | |||
52 | config GENERIC_TIME | 52 | config GENERIC_TIME |
53 | def_bool n | 53 | def_bool n |
54 | 54 | ||
55 | config GENERIC_CLOCKEVENTS | ||
56 | def_bool n | ||
57 | |||
55 | config SYS_SUPPORTS_APM_EMULATION | 58 | config SYS_SUPPORTS_APM_EMULATION |
56 | bool | 59 | bool |
57 | 60 | ||
@@ -436,11 +439,11 @@ endmenu | |||
436 | 439 | ||
437 | menu "Timer and clock configuration" | 440 | menu "Timer and clock configuration" |
438 | 441 | ||
439 | if !GENERIC_TIME | ||
440 | |||
441 | config SH_TMU | 442 | config SH_TMU |
442 | bool "TMU timer support" | 443 | bool "TMU timer support" |
443 | depends on CPU_SH3 || CPU_SH4 | 444 | depends on CPU_SH3 || CPU_SH4 |
445 | select GENERIC_TIME | ||
446 | select GENERIC_CLOCKEVENTS | ||
444 | default y | 447 | default y |
445 | help | 448 | help |
446 | This enables the use of the TMU as the system timer. | 449 | This enables the use of the TMU as the system timer. |
@@ -459,8 +462,6 @@ config SH_MTU2 | |||
459 | help | 462 | help |
460 | This enables the use of the MTU2 as the system timer. | 463 | This enables the use of the MTU2 as the system timer. |
461 | 464 | ||
462 | endif | ||
463 | |||
464 | config SH_TIMER_IRQ | 465 | config SH_TIMER_IRQ |
465 | int | 466 | int |
466 | default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 | 467 | default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 |
@@ -468,24 +469,6 @@ config SH_TIMER_IRQ | |||
468 | default "140" if CPU_SUBTYPE_SH7206 | 469 | default "140" if CPU_SUBTYPE_SH7206 |
469 | default "16" | 470 | default "16" |
470 | 471 | ||
471 | config NO_IDLE_HZ | ||
472 | bool "Dynamic tick timer" | ||
473 | help | ||
474 | Select this option if you want to disable continuous timer ticks | ||
475 | and have them programmed to occur as required. This option saves | ||
476 | power as the system can remain in idle state for longer. | ||
477 | |||
478 | By default dynamic tick is disabled during the boot, and can be | ||
479 | manually enabled with: | ||
480 | |||
481 | echo 1 > /sys/devices/system/timer/timer0/dyn_tick | ||
482 | |||
483 | Alternatively, if you want dynamic tick automatically enabled | ||
484 | during boot, pass "dyntick=enable" via the kernel command string. | ||
485 | |||
486 | Please note that dynamic tick may affect the accuracy of | ||
487 | timekeeping on some platforms depending on the implementation. | ||
488 | |||
489 | config SH_PCLK_FREQ | 472 | config SH_PCLK_FREQ |
490 | int "Peripheral clock frequency (in Hz)" | 473 | int "Peripheral clock frequency (in Hz)" |
491 | default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 | 474 | default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 |
@@ -509,6 +492,8 @@ config SH_CLK_MD | |||
509 | help | 492 | help |
510 | MD2 - MD0 pin setting. | 493 | MD2 - MD0 pin setting. |
511 | 494 | ||
495 | source "kernel/time/Kconfig" | ||
496 | |||
512 | endmenu | 497 | endmenu |
513 | 498 | ||
514 | menu "CPU Frequency scaling" | 499 | menu "CPU Frequency scaling" |
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c index a83a5d9587bb..4058b4f50d44 100644 --- a/arch/sh/boards/landisk/setup.c +++ b/arch/sh/boards/landisk/setup.c | |||
@@ -93,6 +93,7 @@ static void __init landisk_setup(char **cmdline_p) | |||
93 | */ | 93 | */ |
94 | struct sh_machine_vector mv_landisk __initmv = { | 94 | struct sh_machine_vector mv_landisk __initmv = { |
95 | .mv_name = "LANDISK", | 95 | .mv_name = "LANDISK", |
96 | .mv_nr_irqs = 72, | ||
96 | .mv_setup = landisk_setup, | 97 | .mv_setup = landisk_setup, |
97 | .mv_init_irq = init_landisk_IRQ, | 98 | .mv_init_irq = init_landisk_IRQ, |
98 | }; | 99 | }; |
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index 770defed9c4a..52c7bfa57c2c 100644 --- a/arch/sh/boards/se/7751/setup.c +++ b/arch/sh/boards/se/7751/setup.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/sh/kernel/setup_7751se.c | 2 | * linux/arch/sh/boards/se/7751/setup.c |
3 | * | 3 | * |
4 | * Copyright (C) 2000 Kazumoto Kojima | 4 | * Copyright (C) 2000 Kazumoto Kojima |
5 | * | 5 | * |
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile index 6cb92676c5fc..e13f06bebd92 100644 --- a/arch/sh/drivers/Makefile +++ b/arch/sh/drivers/Makefile | |||
@@ -2,8 +2,9 @@ | |||
2 | # Makefile for the Linux SuperH-specific device drivers. | 2 | # Makefile for the Linux SuperH-specific device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += dma/ | ||
6 | |||
5 | obj-$(CONFIG_PCI) += pci/ | 7 | obj-$(CONFIG_PCI) += pci/ |
6 | obj-$(CONFIG_SH_DMA) += dma/ | ||
7 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ | 8 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ |
8 | obj-$(CONFIG_PUSH_SWITCH) += push-switch.o | 9 | obj-$(CONFIG_PUSH_SWITCH) += push-switch.o |
9 | obj-$(CONFIG_HEARTBEAT) += heartbeat.o | 10 | obj-$(CONFIG_HEARTBEAT) += heartbeat.o |
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index defc13c37d48..99935f9daf4b 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig | |||
@@ -1,12 +1,12 @@ | |||
1 | menu "DMA support" | 1 | menu "DMA support" |
2 | 2 | ||
3 | config SH_DMA | 3 | config SH_DMA_API |
4 | bool "DMA controller (DMAC) support" | 4 | bool |
5 | help | ||
6 | Selecting this option will provide same API as PC's Direct Memory | ||
7 | Access Controller(8237A) for SuperH DMAC. | ||
8 | 5 | ||
9 | If unsure, say N. | 6 | config SH_DMA |
7 | bool "SuperH on-chip DMA controller (DMAC) support" | ||
8 | select SH_DMA_API | ||
9 | default n | ||
10 | 10 | ||
11 | config NR_ONCHIP_DMA_CHANNELS | 11 | config NR_ONCHIP_DMA_CHANNELS |
12 | depends on SH_DMA | 12 | depends on SH_DMA |
@@ -53,4 +53,12 @@ config DMA_PAGE_OPS_CHANNEL | |||
53 | in case channel 3 is unavailable. On the SH4, channels 1,2, and 3 | 53 | in case channel 3 is unavailable. On the SH4, channels 1,2, and 3 |
54 | are dual-address capable. | 54 | are dual-address capable. |
55 | 55 | ||
56 | config SH_DMABRG | ||
57 | bool "SH7760 DMABRG support" | ||
58 | depends on CPU_SUBTYPE_SH7760 | ||
59 | help | ||
60 | The DMABRG does data transfers from main memory to Audio/USB units | ||
61 | of the SH7760. | ||
62 | Say Y if you want to use Audio/USB DMA on your SH7760 board. | ||
63 | |||
56 | endmenu | 64 | endmenu |
diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile index db1295d32268..1ac812d24488 100644 --- a/arch/sh/drivers/dma/Makefile +++ b/arch/sh/drivers/dma/Makefile | |||
@@ -2,8 +2,8 @@ | |||
2 | # Makefile for the SuperH DMA specific kernel interface routines under Linux. | 2 | # Makefile for the SuperH DMA specific kernel interface routines under Linux. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += dma-api.o | 5 | obj-$(CONFIG_SH_DMA_API) += dma-api.o dma-sysfs.o |
6 | obj-$(CONFIG_ISA_DMA_API) += dma-isa.o | 6 | obj-$(CONFIG_ISA_DMA_API) += dma-isa.o |
7 | obj-$(CONFIG_SYSFS) += dma-sysfs.o | ||
8 | obj-$(CONFIG_SH_DMA) += dma-sh.o | 7 | obj-$(CONFIG_SH_DMA) += dma-sh.o |
9 | obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o | 8 | obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o |
9 | obj-$(CONFIG_SH_DMABRG) += dmabrg.o | ||
diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c new file mode 100644 index 000000000000..9d0a29370f21 --- /dev/null +++ b/arch/sh/drivers/dma/dmabrg.c | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * SH7760 DMABRG IRQ handling | ||
3 | * | ||
4 | * (c) 2007 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com> | ||
5 | * licensed under the GPLv2. | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <asm/dma.h> | ||
12 | #include <asm/dmabrg.h> | ||
13 | #include <asm/io.h> | ||
14 | |||
15 | /* | ||
16 | * The DMABRG is a special DMA unit within the SH7760. It does transfers | ||
17 | * from USB-SRAM/Audio units to main memory (and also the LCDC; but that | ||
18 | * part is sensibly placed in the LCDC registers and requires no irqs) | ||
19 | * It has 3 IRQ lines which trigger 10 events, and works independently | ||
20 | * from the traditional SH DMAC (although it blocks usage of DMAC 0) | ||
21 | * | ||
22 | * BRGIRQID | component | dir | meaning | source | ||
23 | * ----------------------------------------------------- | ||
24 | * 0 | USB-DMA | ... | xfer done | DMABRGI1 | ||
25 | * 1 | USB-UAE | ... | USB addr err.| DMABRGI0 | ||
26 | * 2 | HAC0/SSI0 | play| all done | DMABRGI1 | ||
27 | * 3 | HAC0/SSI0 | play| half done | DMABRGI2 | ||
28 | * 4 | HAC0/SSI0 | rec | all done | DMABRGI1 | ||
29 | * 5 | HAC0/SSI0 | rec | half done | DMABRGI2 | ||
30 | * 6 | HAC1/SSI1 | play| all done | DMABRGI1 | ||
31 | * 7 | HAC1/SSI1 | play| half done | DMABRGI2 | ||
32 | * 8 | HAC1/SSI1 | rec | all done | DMABRGI1 | ||
33 | * 9 | HAC1/SSI1 | rec | half done | DMABRGI2 | ||
34 | * | ||
35 | * all can be enabled/disabled in the DMABRGCR register, | ||
36 | * as well as checked if they occured. | ||
37 | * | ||
38 | * DMABRGI0 services USB DMA Address errors, but it still must be | ||
39 | * enabled/acked in the DMABRGCR register. USB-DMA complete indicator | ||
40 | * is grouped together with the audio buffer end indicators, too bad... | ||
41 | * | ||
42 | * DMABRGCR: Bits 31-24: audio-dma ENABLE flags, | ||
43 | * Bits 23-16: audio-dma STATUS flags, | ||
44 | * Bits 9-8: USB error/xfer ENABLE, | ||
45 | * Bits 1-0: USB error/xfer STATUS. | ||
46 | * Ack an IRQ by writing 0 to the STATUS flag. | ||
47 | * Mask IRQ by writing 0 to ENABLE flag. | ||
48 | * | ||
49 | * Usage is almost like with any other IRQ: | ||
50 | * dmabrg_request_irq(BRGIRQID, handler, data) | ||
51 | * dmabrg_free_irq(BRGIRQID) | ||
52 | * | ||
53 | * handler prototype: void brgirqhandler(void *data) | ||
54 | */ | ||
55 | |||
56 | #define DMARSRA 0xfe090000 | ||
57 | #define DMAOR 0xffa00040 | ||
58 | #define DMACHCR0 0xffa0000c | ||
59 | #define DMABRGCR 0xfe3c0000 | ||
60 | |||
61 | #define DMAOR_BRG 0x0000c000 | ||
62 | #define DMAOR_DMEN 0x00000001 | ||
63 | |||
64 | #define DMABRGI0 68 | ||
65 | #define DMABRGI1 69 | ||
66 | #define DMABRGI2 70 | ||
67 | |||
68 | struct dmabrg_handler { | ||
69 | void (*handler)(void *); | ||
70 | void *data; | ||
71 | } *dmabrg_handlers; | ||
72 | |||
73 | static inline void dmabrg_call_handler(int i) | ||
74 | { | ||
75 | dmabrg_handlers[i].handler(dmabrg_handlers[i].data); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * main DMABRG irq handler. It acks irqs and then | ||
80 | * handles every set and unmasked bit sequentially. | ||
81 | * No locking and no validity checks; it should be | ||
82 | * as fast as possible (audio!) | ||
83 | */ | ||
84 | static irqreturn_t dmabrg_irq(int irq, void *data) | ||
85 | { | ||
86 | unsigned long dcr; | ||
87 | unsigned int i; | ||
88 | |||
89 | dcr = ctrl_inl(DMABRGCR); | ||
90 | ctrl_outl(dcr & ~0x00ff0003, DMABRGCR); /* ack all */ | ||
91 | dcr &= dcr >> 8; /* ignore masked */ | ||
92 | |||
93 | /* USB stuff, get it out of the way first */ | ||
94 | if (dcr & 1) | ||
95 | dmabrg_call_handler(DMABRGIRQ_USBDMA); | ||
96 | if (dcr & 2) | ||
97 | dmabrg_call_handler(DMABRGIRQ_USBDMAERR); | ||
98 | |||
99 | /* Audio */ | ||
100 | dcr >>= 16; | ||
101 | while (dcr) { | ||
102 | i = __ffs(dcr); | ||
103 | dcr &= dcr - 1; | ||
104 | dmabrg_call_handler(i + DMABRGIRQ_A0TXF); | ||
105 | } | ||
106 | return IRQ_HANDLED; | ||
107 | } | ||
108 | |||
109 | static void dmabrg_disable_irq(unsigned int dmairq) | ||
110 | { | ||
111 | unsigned long dcr; | ||
112 | dcr = ctrl_inl(DMABRGCR); | ||
113 | dcr &= ~(1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8)); | ||
114 | ctrl_outl(dcr, DMABRGCR); | ||
115 | } | ||
116 | |||
117 | static void dmabrg_enable_irq(unsigned int dmairq) | ||
118 | { | ||
119 | unsigned long dcr; | ||
120 | dcr = ctrl_inl(DMABRGCR); | ||
121 | dcr |= (1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8)); | ||
122 | ctrl_outl(dcr, DMABRGCR); | ||
123 | } | ||
124 | |||
125 | int dmabrg_request_irq(unsigned int dmairq, void(*handler)(void*), | ||
126 | void *data) | ||
127 | { | ||
128 | if ((dmairq > 9) || !handler) | ||
129 | return -ENOENT; | ||
130 | if (dmabrg_handlers[dmairq].handler) | ||
131 | return -EBUSY; | ||
132 | |||
133 | dmabrg_handlers[dmairq].handler = handler; | ||
134 | dmabrg_handlers[dmairq].data = data; | ||
135 | |||
136 | dmabrg_enable_irq(dmairq); | ||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(dmabrg_request_irq); | ||
140 | |||
141 | void dmabrg_free_irq(unsigned int dmairq) | ||
142 | { | ||
143 | if (likely(dmairq < 10)) { | ||
144 | dmabrg_disable_irq(dmairq); | ||
145 | dmabrg_handlers[dmairq].handler = NULL; | ||
146 | dmabrg_handlers[dmairq].data = NULL; | ||
147 | } | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(dmabrg_free_irq); | ||
150 | |||
151 | static int __init dmabrg_init(void) | ||
152 | { | ||
153 | unsigned long or; | ||
154 | int ret; | ||
155 | |||
156 | dmabrg_handlers = kzalloc(10 * sizeof(struct dmabrg_handler), | ||
157 | GFP_KERNEL); | ||
158 | if (!dmabrg_handlers) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | #ifdef CONFIG_SH_DMA | ||
162 | /* request DMAC channel 0 before anyone else can get it */ | ||
163 | ret = request_dma(0, "DMAC 0 (DMABRG)"); | ||
164 | if (ret < 0) | ||
165 | printk(KERN_INFO "DMABRG: DMAC ch0 not reserved!\n"); | ||
166 | #endif | ||
167 | |||
168 | ctrl_outl(0, DMABRGCR); | ||
169 | ctrl_outl(0, DMACHCR0); | ||
170 | ctrl_outl(0x94000000, DMARSRA); /* enable DMABRG in DMAC 0 */ | ||
171 | |||
172 | /* enable DMABRG mode, enable the DMAC */ | ||
173 | or = ctrl_inl(DMAOR); | ||
174 | ctrl_outl(or | DMAOR_BRG | DMAOR_DMEN, DMAOR); | ||
175 | |||
176 | ret = request_irq(DMABRGI0, dmabrg_irq, IRQF_DISABLED, | ||
177 | "DMABRG USB address error", NULL); | ||
178 | if (ret) | ||
179 | goto out0; | ||
180 | |||
181 | ret = request_irq(DMABRGI1, dmabrg_irq, IRQF_DISABLED, | ||
182 | "DMABRG Transfer End", NULL); | ||
183 | if (ret) | ||
184 | goto out1; | ||
185 | |||
186 | ret = request_irq(DMABRGI2, dmabrg_irq, IRQF_DISABLED, | ||
187 | "DMABRG Transfer Half", NULL); | ||
188 | if (ret == 0) | ||
189 | return ret; | ||
190 | |||
191 | free_irq(DMABRGI1, 0); | ||
192 | out1: free_irq(DMABRGI0, 0); | ||
193 | out0: kfree(dmabrg_handlers); | ||
194 | return ret; | ||
195 | } | ||
196 | subsys_initcall(dmabrg_init); | ||
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile index 350972ae9410..965fa2572b23 100644 --- a/arch/sh/kernel/cpu/sh2a/Makefile +++ b/arch/sh/kernel/cpu/sh2a/Makefile | |||
@@ -2,9 +2,8 @@ | |||
2 | # Makefile for the Linux/SuperH SH-2A backends. | 2 | # Makefile for the Linux/SuperH SH-2A backends. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := common.o probe.o | 5 | obj-y := common.o probe.o opcode_helper.o |
6 | 6 | ||
7 | common-y += $(addprefix ../sh2/, ex.o) | 7 | common-y += $(addprefix ../sh2/, ex.o entry.o) |
8 | common-y += $(addprefix ../sh2/, entry.o) | ||
9 | 8 | ||
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o | 9 | obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o |
diff --git a/arch/sh/kernel/cpu/sh2a/opcode_helper.c b/arch/sh/kernel/cpu/sh2a/opcode_helper.c new file mode 100644 index 000000000000..9704b7926d8b --- /dev/null +++ b/arch/sh/kernel/cpu/sh2a/opcode_helper.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh2a/opcode_helper.c | ||
3 | * | ||
4 | * Helper for the SH-2A 32-bit opcodes. | ||
5 | * | ||
6 | * Copyright (C) 2007 Paul Mundt | ||
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 | #include <linux/kernel.h> | ||
13 | #include <asm/system.h> | ||
14 | |||
15 | /* | ||
16 | * Instructions on SH are generally fixed at 16-bits, however, SH-2A | ||
17 | * introduces some 32-bit instructions. Since there are no real | ||
18 | * constraints on their use (and they can be mixed and matched), we need | ||
19 | * to check the instruction encoding to work out if it's a true 32-bit | ||
20 | * instruction or not. | ||
21 | * | ||
22 | * Presently, 32-bit opcodes have only slight variations in what the | ||
23 | * actual encoding looks like in the first-half of the instruction, which | ||
24 | * makes it fairly straightforward to differentiate from the 16-bit ones. | ||
25 | * | ||
26 | * First 16-bits of encoding Used by | ||
27 | * | ||
28 | * 0011nnnnmmmm0001 mov.b, mov.w, mov.l, fmov.d, | ||
29 | * fmov.s, movu.b, movu.w | ||
30 | * | ||
31 | * 0011nnnn0iii1001 bclr.b, bld.b, bset.b, bst.b, band.b, | ||
32 | * bandnot.b, bldnot.b, bor.b, bornot.b, | ||
33 | * bxor.b | ||
34 | * | ||
35 | * 0000nnnniiii0000 movi20 | ||
36 | * 0000nnnniiii0001 movi20s | ||
37 | */ | ||
38 | unsigned int instruction_size(unsigned int insn) | ||
39 | { | ||
40 | /* Look for the common cases */ | ||
41 | switch ((insn & 0xf00f)) { | ||
42 | case 0x0000: /* movi20 */ | ||
43 | case 0x0001: /* movi20s */ | ||
44 | case 0x3001: /* 32-bit mov/fmov/movu variants */ | ||
45 | return 4; | ||
46 | } | ||
47 | |||
48 | /* And the special cases.. */ | ||
49 | switch ((insn & 0xf08f)) { | ||
50 | case 0x3009: /* 32-bit b*.b bit operations */ | ||
51 | return 4; | ||
52 | } | ||
53 | |||
54 | return 2; | ||
55 | } | ||
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c index 426f6db01fc6..f455c3509789 100644 --- a/arch/sh/kernel/cpu/sh2a/probe.c +++ b/arch/sh/kernel/cpu/sh2a/probe.c | |||
@@ -18,6 +18,7 @@ int __init detect_cpu_and_cache_system(void) | |||
18 | { | 18 | { |
19 | /* Just SH7206 for now .. */ | 19 | /* Just SH7206 for now .. */ |
20 | current_cpu_data.type = CPU_SH7206; | 20 | current_cpu_data.type = CPU_SH7206; |
21 | current_cpu_data.flags |= CPU_HAS_OP32; | ||
21 | 22 | ||
22 | current_cpu_data.dcache.ways = 4; | 23 | current_cpu_data.dcache.ways = 4; |
23 | current_cpu_data.dcache.way_incr = (1 << 11); | 24 | current_cpu_data.dcache.way_incr = (1 << 11); |
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index f3e827f29a46..832c0b4a1e6c 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/entry.S | 2 | * arch/sh/kernel/cpu/sh3/entry.S |
3 | * | 3 | * |
4 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka | 4 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka |
5 | * Copyright (C) 2003 - 2006 Paul Mundt | 5 | * Copyright (C) 2003 - 2006 Paul Mundt |
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index ba3082d640b5..2b2a9e02fb75 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/cpu/sh3/ex.S | 2 | * arch/sh/kernel/cpu/sh3/ex.S |
3 | * | 3 | * |
4 | * The SH-3 exception vector table. | 4 | * The SH-3 and SH-4 exception vector table. |
5 | 5 | ||
6 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka | 6 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka |
7 | * Copyright (C) 2003 - 2006 Paul Mundt | 7 | * Copyright (C) 2003 - 2006 Paul Mundt |
@@ -9,7 +9,6 @@ | |||
9 | * This file is subject to the terms and conditions of the GNU General Public | 9 | * This file is subject to the terms and conditions of the GNU General Public |
10 | * License. See the file "COPYING" in the main directory of this archive | 10 | * License. See the file "COPYING" in the main directory of this archive |
11 | * for more details. | 11 | * for more details. |
12 | * | ||
13 | */ | 12 | */ |
14 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
15 | 14 | ||
@@ -36,8 +35,12 @@ ENTRY(exception_handling_table) | |||
36 | .long exception_error ! address error load | 35 | .long exception_error ! address error load |
37 | .long exception_error ! address error store /* 100 */ | 36 | .long exception_error ! address error store /* 100 */ |
38 | #endif | 37 | #endif |
39 | .long exception_error ! fpu_exception /* 120 */ | 38 | #if defined(CONFIG_SH_FPU) |
40 | .long exception_error /* 140 */ | 39 | .long do_fpu_error /* 120 */ |
40 | #else | ||
41 | .long exception_error /* 120 */ | ||
42 | #endif | ||
43 | .long exception_error /* 140 */ | ||
41 | .long system_call ! Unconditional Trap /* 160 */ | 44 | .long system_call ! Unconditional Trap /* 160 */ |
42 | .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ | 45 | .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ |
43 | .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ | 46 | .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ |
@@ -55,4 +58,4 @@ ENTRY(user_break_point_trap) | |||
55 | * away offsets can be manually inserted in to their appropriate | 58 | * away offsets can be manually inserted in to their appropriate |
56 | * location via set_exception_table_{evt,vec}(). | 59 | * location via set_exception_table_{evt,vec}(). |
57 | */ | 60 | */ |
58 | .balign 4096,0,4096 | 61 | .balign 4096,0,4096 |
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 19ca68c71884..8add10bd8268 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile | |||
@@ -2,10 +2,10 @@ | |||
2 | # Makefile for the Linux/SuperH SH-4 backends. | 2 | # Makefile for the Linux/SuperH SH-4 backends. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := ex.o probe.o common.o | 5 | obj-y := probe.o common.o |
6 | common-y += $(addprefix ../sh3/, entry.o) | 6 | common-y += $(addprefix ../sh3/, entry.o ex.o) |
7 | 7 | ||
8 | obj-$(CONFIG_SH_FPU) += fpu.o | 8 | obj-$(CONFIG_SH_FPU) += fpu.o |
9 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o | 9 | obj-$(CONFIG_SH_STORE_QUEUES) += sq.o |
10 | 10 | ||
11 | # CPU subtype setup | 11 | # CPU subtype setup |
diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S deleted file mode 100644 index ac8ab57413cc..000000000000 --- a/arch/sh/kernel/cpu/sh4/ex.S +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4/ex.S | ||
3 | * | ||
4 | * The SH-4 exception vector table. | ||
5 | |||
6 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka | ||
7 | * Copyright (C) 2003 - 2006 Paul Mundt | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file "COPYING" in the main directory of this archive | ||
11 | * for more details. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/linkage.h> | ||
15 | |||
16 | .align 2 | ||
17 | .data | ||
18 | |||
19 | ENTRY(exception_handling_table) | ||
20 | .long exception_error /* 000 */ | ||
21 | .long exception_error | ||
22 | #if defined(CONFIG_MMU) | ||
23 | .long tlb_miss_load /* 040 */ | ||
24 | .long tlb_miss_store | ||
25 | .long initial_page_write | ||
26 | .long tlb_protection_violation_load | ||
27 | .long tlb_protection_violation_store | ||
28 | .long address_error_load | ||
29 | .long address_error_store /* 100 */ | ||
30 | #else | ||
31 | .long exception_error ! tlb miss load /* 040 */ | ||
32 | .long exception_error ! tlb miss store | ||
33 | .long exception_error ! initial page write | ||
34 | .long exception_error ! tlb prot violation load | ||
35 | .long exception_error ! tlb prot violation store | ||
36 | .long exception_error ! address error load | ||
37 | .long exception_error ! address error store /* 100 */ | ||
38 | #endif | ||
39 | #if defined(CONFIG_SH_FPU) | ||
40 | .long do_fpu_error /* 120 */ | ||
41 | #else | ||
42 | .long exception_error /* 120 */ | ||
43 | #endif | ||
44 | .long exception_error /* 140 */ | ||
45 | .long system_call ! Unconditional Trap /* 160 */ | ||
46 | .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ | ||
47 | .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ | ||
48 | ENTRY(nmi_slot) | ||
49 | #if defined (CONFIG_KGDB_NMI) | ||
50 | .long debug_enter /* 1C0 */ ! Allow trap to debugger | ||
51 | #else | ||
52 | .long exception_none /* 1C0 */ ! Not implemented yet | ||
53 | #endif | ||
54 | ENTRY(user_break_point_trap) | ||
55 | .long break_point_trap /* 1E0 */ | ||
56 | |||
57 | /* | ||
58 | * Pad the remainder of the table out, exceptions residing in far | ||
59 | * away offsets can be manually inserted in to their appropriate | ||
60 | * location via set_exception_table_{evt,vec}(). | ||
61 | */ | ||
62 | .balign 4096,0,4096 | ||
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index 7624677f6628..d61dd599169f 100644 --- a/arch/sh/kernel/cpu/sh4/fpu.c +++ b/arch/sh/kernel/cpu/sh4/fpu.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/signal.h> | 17 | #include <linux/signal.h> |
18 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
19 | #include <asm/system.h> | ||
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
20 | 21 | ||
21 | /* The PR (precision) bit in the FP Status Register must be clear when | 22 | /* The PR (precision) bit in the FP Status Register must be clear when |
@@ -265,7 +266,7 @@ ieee_fpe_handler (struct pt_regs *regs) | |||
265 | nextpc = regs->pr; | 266 | nextpc = regs->pr; |
266 | finsn = *(unsigned short *) (regs->pc + 2); | 267 | finsn = *(unsigned short *) (regs->pc + 2); |
267 | } else { | 268 | } else { |
268 | nextpc = regs->pc + 2; | 269 | nextpc = regs->pc + instruction_size(insn); |
269 | finsn = insn; | 270 | finsn = insn; |
270 | } | 271 | } |
271 | 272 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh73180.c b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c index 2fa5cb2ae68d..6d5ba373a75e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh73180.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/cpu/sh4/clock-sh73180.c | 2 | * arch/sh/kernel/cpu/sh4a/clock-sh73180.c |
3 | * | 3 | * |
4 | * SH73180 support for the clock framework | 4 | * SH73180 support for the clock framework |
5 | * | 5 | * |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 1707a213f0cf..7adc4f16e95a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/cpu/sh4/clock-sh7343.c | 2 | * arch/sh/kernel/cpu/sh4a/clock-sh7343.c |
3 | * | 3 | * |
4 | * SH7343/SH7722 support for the clock framework | 4 | * SH7343/SH7722 support for the clock framework |
5 | * | 5 | * |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c index c8694bac6477..8e236062c721 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/cpu/sh4/clock-sh7770.c | 2 | * arch/sh/kernel/cpu/sh4a/clock-sh7770.c |
3 | * | 3 | * |
4 | * SH7770 support for the clock framework | 4 | * SH7770 support for the clock framework |
5 | * | 5 | * |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index 9e6a216750c8..01f3da619d3d 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/cpu/sh4/clock-sh7780.c | 2 | * arch/sh/kernel/cpu/sh4a/clock-sh7780.c |
3 | * | 3 | * |
4 | * SH7780 support for the clock framework | 4 | * SH7780 support for the clock framework |
5 | * | 5 | * |
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 329b3f3051de..6b4f5748d0be 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c | |||
@@ -15,9 +15,12 @@ | |||
15 | #include <linux/pm.h> | 15 | #include <linux/pm.h> |
16 | #include <linux/kallsyms.h> | 16 | #include <linux/kallsyms.h> |
17 | #include <linux/kexec.h> | 17 | #include <linux/kexec.h> |
18 | #include <asm/kdebug.h> | 18 | #include <linux/kdebug.h> |
19 | #include <linux/tick.h> | ||
19 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
20 | #include <asm/mmu_context.h> | 21 | #include <asm/mmu_context.h> |
22 | #include <asm/pgalloc.h> | ||
23 | #include <asm/system.h> | ||
21 | #include <asm/ubc.h> | 24 | #include <asm/ubc.h> |
22 | 25 | ||
23 | static int hlt_counter; | 26 | static int hlt_counter; |
@@ -58,12 +61,15 @@ void cpu_idle(void) | |||
58 | if (!idle) | 61 | if (!idle) |
59 | idle = default_idle; | 62 | idle = default_idle; |
60 | 63 | ||
64 | tick_nohz_stop_sched_tick(); | ||
61 | while (!need_resched()) | 65 | while (!need_resched()) |
62 | idle(); | 66 | idle(); |
67 | tick_nohz_restart_sched_tick(); | ||
63 | 68 | ||
64 | preempt_enable_no_resched(); | 69 | preempt_enable_no_resched(); |
65 | schedule(); | 70 | schedule(); |
66 | preempt_disable(); | 71 | preempt_disable(); |
72 | check_pgt_cache(); | ||
67 | } | 73 | } |
68 | } | 74 | } |
69 | 75 | ||
@@ -495,9 +501,9 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, | |||
495 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | 501 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); |
496 | 502 | ||
497 | /* Rewind */ | 503 | /* Rewind */ |
498 | regs->pc -= 2; | 504 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); |
499 | 505 | ||
500 | if (notify_die(DIE_TRAP, regs, regs->tra & 0xff, | 506 | if (notify_die(DIE_TRAP, "debug trap", regs, 0, regs->tra & 0xff, |
501 | SIGTRAP) == NOTIFY_STOP) | 507 | SIGTRAP) == NOTIFY_STOP) |
502 | return; | 508 | return; |
503 | 509 | ||
@@ -514,9 +520,9 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, | |||
514 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | 520 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); |
515 | 521 | ||
516 | /* Rewind */ | 522 | /* Rewind */ |
517 | regs->pc -= 2; | 523 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); |
518 | 524 | ||
519 | if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff, | 525 | if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, |
520 | SIGTRAP) == NOTIFY_STOP) | 526 | SIGTRAP) == NOTIFY_STOP) |
521 | return; | 527 | return; |
522 | 528 | ||
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 477d2a854fc4..c27729135935 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -431,7 +431,7 @@ const char *get_cpu_subtype(struct sh_cpuinfo *c) | |||
431 | /* Symbolic CPU flags, keep in sync with asm/cpu-features.h */ | 431 | /* Symbolic CPU flags, keep in sync with asm/cpu-features.h */ |
432 | static const char *cpu_flags[] = { | 432 | static const char *cpu_flags[] = { |
433 | "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", | 433 | "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", |
434 | "ptea", "llsc", "l2", NULL | 434 | "ptea", "llsc", "l2", "op32", NULL |
435 | }; | 435 | }; |
436 | 436 | ||
437 | static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c) | 437 | static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c) |
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index fa91641c1f62..c1cfcb9f047c 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c | |||
@@ -58,8 +58,6 @@ EXPORT_SYMBOL(__udelay); | |||
58 | EXPORT_SYMBOL(__ndelay); | 58 | EXPORT_SYMBOL(__ndelay); |
59 | EXPORT_SYMBOL(__const_udelay); | 59 | EXPORT_SYMBOL(__const_udelay); |
60 | 60 | ||
61 | EXPORT_SYMBOL(__div64_32); | ||
62 | |||
63 | #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name) | 61 | #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name) |
64 | 62 | ||
65 | /* These symbols are generated by the compiler itself */ | 63 | /* These symbols are generated by the compiler itself */ |
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index eb0191c374b6..b32c35a7c0a3 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/personality.h> | 23 | #include <linux/personality.h> |
24 | #include <linux/binfmts.h> | 24 | #include <linux/binfmts.h> |
25 | #include <linux/freezer.h> | 25 | #include <linux/freezer.h> |
26 | 26 | #include <asm/system.h> | |
27 | #include <asm/ucontext.h> | 27 | #include <asm/ucontext.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/pgtable.h> | 29 | #include <asm/pgtable.h> |
@@ -500,7 +500,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
500 | } | 500 | } |
501 | /* fallthrough */ | 501 | /* fallthrough */ |
502 | case -ERESTARTNOINTR: | 502 | case -ERESTARTNOINTR: |
503 | regs->pc -= 2; | 503 | regs->pc -= instruction_size( |
504 | ctrl_inw(regs->pc - 4)); | ||
505 | break; | ||
504 | } | 506 | } |
505 | } else { | 507 | } else { |
506 | /* gUSA handling */ | 508 | /* gUSA handling */ |
@@ -516,7 +518,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
516 | regs->regs[15] = regs->regs[1]; | 518 | regs->regs[15] = regs->regs[1]; |
517 | if (regs->pc < regs->regs[0]) | 519 | if (regs->pc < regs->regs[0]) |
518 | /* Go to rewind point #1 */ | 520 | /* Go to rewind point #1 */ |
519 | regs->pc = regs->regs[0] + offset - 2; | 521 | regs->pc = regs->regs[0] + offset - |
522 | instruction_size(ctrl_inw(regs->pc-4)); | ||
520 | } | 523 | } |
521 | #ifdef CONFIG_PREEMPT | 524 | #ifdef CONFIG_PREEMPT |
522 | local_irq_restore(flags); | 525 | local_irq_restore(flags); |
@@ -600,9 +603,9 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) | |||
600 | regs->regs[0] == -ERESTARTSYS || | 603 | regs->regs[0] == -ERESTARTSYS || |
601 | regs->regs[0] == -ERESTARTNOINTR) { | 604 | regs->regs[0] == -ERESTARTNOINTR) { |
602 | regs->regs[0] = save_r0; | 605 | regs->regs[0] = save_r0; |
603 | regs->pc -= 2; | 606 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); |
604 | } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { | 607 | } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { |
605 | regs->pc -= 2; | 608 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); |
606 | regs->regs[3] = __NR_restart_syscall; | 609 | regs->regs[3] = __NR_restart_syscall; |
607 | } | 610 | } |
608 | } | 611 | } |
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c index 4bdd2f83535d..d41e561be20e 100644 --- a/arch/sh/kernel/stacktrace.c +++ b/arch/sh/kernel/stacktrace.c | |||
@@ -17,7 +17,7 @@ | |||
17 | /* | 17 | /* |
18 | * Save stack-backtrace addresses into a stack_trace buffer. | 18 | * Save stack-backtrace addresses into a stack_trace buffer. |
19 | */ | 19 | */ |
20 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | 20 | void save_stack_trace(struct stack_trace *trace) |
21 | { | 21 | { |
22 | unsigned long *sp = (unsigned long *)current_stack_pointer; | 22 | unsigned long *sp = (unsigned long *)current_stack_pointer; |
23 | 23 | ||
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S index 38fc8cd3ea3a..4357d1a6358f 100644 --- a/arch/sh/kernel/syscalls.S +++ b/arch/sh/kernel/syscalls.S | |||
@@ -354,3 +354,4 @@ ENTRY(sys_call_table) | |||
354 | .long sys_move_pages | 354 | .long sys_move_pages |
355 | .long sys_getcpu | 355 | .long sys_getcpu |
356 | .long sys_epoll_pwait | 356 | .long sys_epoll_pwait |
357 | .long sys_utimensat /* 320 */ | ||
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index d47e775962e9..a3a67d151e52 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka | 4 | * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka |
5 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | 5 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> |
6 | * Copyright (C) 2002 - 2006 Paul Mundt | 6 | * Copyright (C) 2002 - 2007 Paul Mundt |
7 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> | 7 | * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> |
8 | * | 8 | * |
9 | * Some code taken from i386 version. | 9 | * Some code taken from i386 version. |
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/profile.h> | 15 | #include <linux/profile.h> |
16 | #include <linux/timex.h> | 16 | #include <linux/timex.h> |
17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/clockchips.h> | ||
18 | #include <asm/clock.h> | 19 | #include <asm/clock.h> |
19 | #include <asm/rtc.h> | 20 | #include <asm/rtc.h> |
20 | #include <asm/timer.h> | 21 | #include <asm/timer.h> |
@@ -38,6 +39,14 @@ static int null_rtc_set_time(const time_t secs) | |||
38 | return 0; | 39 | return 0; |
39 | } | 40 | } |
40 | 41 | ||
42 | /* | ||
43 | * Null high precision timer functions for systems lacking one. | ||
44 | */ | ||
45 | static cycle_t null_hpt_read(void) | ||
46 | { | ||
47 | return 0; | ||
48 | } | ||
49 | |||
41 | void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; | 50 | void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; |
42 | int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; | 51 | int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; |
43 | 52 | ||
@@ -101,6 +110,7 @@ int do_settimeofday(struct timespec *tv) | |||
101 | EXPORT_SYMBOL(do_settimeofday); | 110 | EXPORT_SYMBOL(do_settimeofday); |
102 | #endif /* !CONFIG_GENERIC_TIME */ | 111 | #endif /* !CONFIG_GENERIC_TIME */ |
103 | 112 | ||
113 | #ifndef CONFIG_GENERIC_CLOCKEVENTS | ||
104 | /* last time the RTC clock got updated */ | 114 | /* last time the RTC clock got updated */ |
105 | static long last_rtc_update; | 115 | static long last_rtc_update; |
106 | 116 | ||
@@ -138,6 +148,7 @@ void handle_timer_tick(void) | |||
138 | last_rtc_update = xtime.tv_sec - 600; | 148 | last_rtc_update = xtime.tv_sec - 600; |
139 | } | 149 | } |
140 | } | 150 | } |
151 | #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ | ||
141 | 152 | ||
142 | #ifdef CONFIG_PM | 153 | #ifdef CONFIG_PM |
143 | int timer_suspend(struct sys_device *dev, pm_message_t state) | 154 | int timer_suspend(struct sys_device *dev, pm_message_t state) |
@@ -168,136 +179,58 @@ static struct sysdev_class timer_sysclass = { | |||
168 | .resume = timer_resume, | 179 | .resume = timer_resume, |
169 | }; | 180 | }; |
170 | 181 | ||
171 | #ifdef CONFIG_NO_IDLE_HZ | 182 | static int __init timer_init_sysfs(void) |
172 | static int timer_dyn_tick_enable(void) | ||
173 | { | 183 | { |
174 | struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; | 184 | int ret = sysdev_class_register(&timer_sysclass); |
175 | unsigned long flags; | 185 | if (ret != 0) |
176 | int ret = -ENODEV; | 186 | return ret; |
177 | |||
178 | if (dyn_tick) { | ||
179 | spin_lock_irqsave(&dyn_tick->lock, flags); | ||
180 | ret = 0; | ||
181 | if (!(dyn_tick->state & DYN_TICK_ENABLED)) { | ||
182 | ret = dyn_tick->enable(); | ||
183 | |||
184 | if (ret == 0) | ||
185 | dyn_tick->state |= DYN_TICK_ENABLED; | ||
186 | } | ||
187 | spin_unlock_irqrestore(&dyn_tick->lock, flags); | ||
188 | } | ||
189 | 187 | ||
190 | return ret; | 188 | sys_timer->dev.cls = &timer_sysclass; |
189 | return sysdev_register(&sys_timer->dev); | ||
191 | } | 190 | } |
191 | device_initcall(timer_init_sysfs); | ||
192 | 192 | ||
193 | static int timer_dyn_tick_disable(void) | 193 | void (*board_time_init)(void); |
194 | { | ||
195 | struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; | ||
196 | unsigned long flags; | ||
197 | int ret = -ENODEV; | ||
198 | |||
199 | if (dyn_tick) { | ||
200 | spin_lock_irqsave(&dyn_tick->lock, flags); | ||
201 | ret = 0; | ||
202 | if (dyn_tick->state & DYN_TICK_ENABLED) { | ||
203 | ret = dyn_tick->disable(); | ||
204 | |||
205 | if (ret == 0) | ||
206 | dyn_tick->state &= ~DYN_TICK_ENABLED; | ||
207 | } | ||
208 | spin_unlock_irqrestore(&dyn_tick->lock, flags); | ||
209 | } | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | 194 | ||
214 | /* | 195 | /* |
215 | * Reprogram the system timer for at least the calculated time interval. | 196 | * Shamelessly based on the MIPS and Sparc64 work. |
216 | * This function should be called from the idle thread with IRQs disabled, | ||
217 | * immediately before sleeping. | ||
218 | */ | 197 | */ |
219 | void timer_dyn_reprogram(void) | 198 | static unsigned long timer_ticks_per_nsec_quotient __read_mostly; |
220 | { | 199 | unsigned long sh_hpt_frequency = 0; |
221 | struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; | 200 | |
222 | unsigned long next, seq, flags; | 201 | #define NSEC_PER_CYC_SHIFT 10 |
223 | 202 | ||
224 | if (!dyn_tick) | 203 | struct clocksource clocksource_sh = { |
225 | return; | 204 | .name = "SuperH", |
226 | 205 | .rating = 200, | |
227 | spin_lock_irqsave(&dyn_tick->lock, flags); | 206 | .mask = CLOCKSOURCE_MASK(32), |
228 | if (dyn_tick->state & DYN_TICK_ENABLED) { | 207 | .read = null_hpt_read, |
229 | next = next_timer_interrupt(); | 208 | .shift = 16, |
230 | do { | 209 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
231 | seq = read_seqbegin(&xtime_lock); | 210 | }; |
232 | dyn_tick->reprogram(next - jiffies); | ||
233 | } while (read_seqretry(&xtime_lock, seq)); | ||
234 | } | ||
235 | spin_unlock_irqrestore(&dyn_tick->lock, flags); | ||
236 | } | ||
237 | 211 | ||
238 | static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) | 212 | static void __init init_sh_clocksource(void) |
239 | { | 213 | { |
240 | return sprintf(buf, "%i\n", | 214 | if (!sh_hpt_frequency || clocksource_sh.read == null_hpt_read) |
241 | (sys_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); | 215 | return; |
242 | } | ||
243 | 216 | ||
244 | static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, | 217 | clocksource_sh.mult = clocksource_hz2mult(sh_hpt_frequency, |
245 | size_t count) | 218 | clocksource_sh.shift); |
246 | { | ||
247 | unsigned int enable = simple_strtoul(buf, NULL, 2); | ||
248 | 219 | ||
249 | if (enable) | 220 | timer_ticks_per_nsec_quotient = |
250 | timer_dyn_tick_enable(); | 221 | clocksource_hz2mult(sh_hpt_frequency, NSEC_PER_CYC_SHIFT); |
251 | else | ||
252 | timer_dyn_tick_disable(); | ||
253 | 222 | ||
254 | return count; | 223 | clocksource_register(&clocksource_sh); |
255 | } | 224 | } |
256 | static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); | ||
257 | 225 | ||
258 | /* | 226 | #ifdef CONFIG_GENERIC_TIME |
259 | * dyntick=enable|disable | 227 | unsigned long long sched_clock(void) |
260 | */ | ||
261 | static char dyntick_str[4] __initdata = ""; | ||
262 | |||
263 | static int __init dyntick_setup(char *str) | ||
264 | { | 228 | { |
265 | if (str) | 229 | unsigned long long ticks = clocksource_sh.read(); |
266 | strlcpy(dyntick_str, str, sizeof(dyntick_str)); | 230 | return (ticks * timer_ticks_per_nsec_quotient) >> NSEC_PER_CYC_SHIFT; |
267 | return 1; | ||
268 | } | 231 | } |
269 | |||
270 | __setup("dyntick=", dyntick_setup); | ||
271 | #endif | ||
272 | |||
273 | static int __init timer_init_sysfs(void) | ||
274 | { | ||
275 | int ret = sysdev_class_register(&timer_sysclass); | ||
276 | if (ret != 0) | ||
277 | return ret; | ||
278 | |||
279 | sys_timer->dev.cls = &timer_sysclass; | ||
280 | ret = sysdev_register(&sys_timer->dev); | ||
281 | |||
282 | #ifdef CONFIG_NO_IDLE_HZ | ||
283 | if (ret == 0 && sys_timer->dyn_tick) { | ||
284 | ret = sysdev_create_file(&sys_timer->dev, &attr_dyn_tick); | ||
285 | |||
286 | /* | ||
287 | * Turn on dynamic tick after calibrate delay | ||
288 | * for correct bogomips | ||
289 | */ | ||
290 | if (ret == 0 && dyntick_str[0] == 'e') | ||
291 | ret = timer_dyn_tick_enable(); | ||
292 | } | ||
293 | #endif | 232 | #endif |
294 | 233 | ||
295 | return ret; | ||
296 | } | ||
297 | device_initcall(timer_init_sysfs); | ||
298 | |||
299 | void (*board_time_init)(void); | ||
300 | |||
301 | void __init time_init(void) | 234 | void __init time_init(void) |
302 | { | 235 | { |
303 | if (board_time_init) | 236 | if (board_time_init) |
@@ -316,10 +249,15 @@ void __init time_init(void) | |||
316 | sys_timer = get_sys_timer(); | 249 | sys_timer = get_sys_timer(); |
317 | printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); | 250 | printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); |
318 | 251 | ||
319 | #ifdef CONFIG_NO_IDLE_HZ | 252 | if (sys_timer->ops->read) |
320 | if (sys_timer->dyn_tick) | 253 | clocksource_sh.read = sys_timer->ops->read; |
321 | spin_lock_init(&sys_timer->dyn_tick->lock); | 254 | |
322 | #endif | 255 | init_sh_clocksource(); |
256 | |||
257 | if (sh_hpt_frequency) | ||
258 | printk("Using %lu.%03lu MHz high precision timer.\n", | ||
259 | ((sh_hpt_frequency + 500) / 1000) / 1000, | ||
260 | ((sh_hpt_frequency + 500) / 1000) % 1000); | ||
323 | 261 | ||
324 | #if defined(CONFIG_SH_KGDB) | 262 | #if defined(CONFIG_SH_KGDB) |
325 | /* | 263 | /* |
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index d9e3151c891e..2d997e2a5b6c 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/timers/timer-tmu.c - TMU Timer Support | 2 | * arch/sh/kernel/timers/timer-tmu.c - TMU Timer Support |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Paul Mundt | 4 | * Copyright (C) 2005 - 2007 Paul Mundt |
5 | * | 5 | * |
6 | * TMU handling code hacked out of arch/sh/kernel/time.c | 6 | * TMU handling code hacked out of arch/sh/kernel/time.c |
7 | * | 7 | * |
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/seqlock.h> | 20 | #include <linux/seqlock.h> |
21 | #include <linux/clockchips.h> | ||
21 | #include <asm/timer.h> | 22 | #include <asm/timer.h> |
22 | #include <asm/rtc.h> | 23 | #include <asm/rtc.h> |
23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
@@ -25,56 +26,75 @@ | |||
25 | #include <asm/clock.h> | 26 | #include <asm/clock.h> |
26 | 27 | ||
27 | #define TMU_TOCR_INIT 0x00 | 28 | #define TMU_TOCR_INIT 0x00 |
28 | #define TMU0_TCR_INIT 0x0020 | 29 | #define TMU_TCR_INIT 0x0020 |
29 | #define TMU_TSTR_INIT 1 | ||
30 | 30 | ||
31 | #define TMU0_TCR_CALIB 0x0000 | 31 | static int tmu_timer_start(void) |
32 | { | ||
33 | ctrl_outb(ctrl_inb(TMU_TSTR) | 0x3, TMU_TSTR); | ||
34 | return 0; | ||
35 | } | ||
32 | 36 | ||
33 | static unsigned long tmu_timer_get_offset(void) | 37 | static void tmu0_timer_set_interval(unsigned long interval, unsigned int reload) |
34 | { | 38 | { |
35 | int count; | 39 | ctrl_outl(interval, TMU0_TCNT); |
36 | static int count_p = 0x7fffffff; /* for the first call after boot */ | ||
37 | static unsigned long jiffies_p = 0; | ||
38 | 40 | ||
39 | /* | 41 | /* |
40 | * cache volatile jiffies temporarily; we have IRQs turned off. | 42 | * TCNT reloads from TCOR on underflow, clear it if we don't |
43 | * intend to auto-reload | ||
41 | */ | 44 | */ |
42 | unsigned long jiffies_t; | 45 | if (reload) |
46 | ctrl_outl(interval, TMU0_TCOR); | ||
47 | else | ||
48 | ctrl_outl(0, TMU0_TCOR); | ||
43 | 49 | ||
44 | /* timer count may underflow right here */ | 50 | tmu_timer_start(); |
45 | count = ctrl_inl(TMU0_TCNT); /* read the latched count */ | 51 | } |
46 | 52 | ||
47 | jiffies_t = jiffies; | 53 | static int tmu_timer_stop(void) |
54 | { | ||
55 | ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x3, TMU_TSTR); | ||
56 | return 0; | ||
57 | } | ||
48 | 58 | ||
49 | /* | 59 | static cycle_t tmu_timer_read(void) |
50 | * avoiding timer inconsistencies (they are rare, but they happen)... | 60 | { |
51 | * there is one kind of problem that must be avoided here: | 61 | return ~ctrl_inl(TMU1_TCNT); |
52 | * 1. the timer counter underflows | 62 | } |
53 | */ | 63 | |
64 | static int tmu_set_next_event(unsigned long cycles, | ||
65 | struct clock_event_device *evt) | ||
66 | { | ||
67 | tmu0_timer_set_interval(cycles, 1); | ||
68 | return 0; | ||
69 | } | ||
54 | 70 | ||
55 | if (jiffies_t == jiffies_p) { | 71 | static void tmu_set_mode(enum clock_event_mode mode, |
56 | if (count > count_p) { | 72 | struct clock_event_device *evt) |
57 | /* the nutcase */ | 73 | { |
58 | if (ctrl_inw(TMU0_TCR) & 0x100) { /* Check UNF bit */ | 74 | switch (mode) { |
59 | count -= LATCH; | 75 | case CLOCK_EVT_MODE_PERIODIC: |
60 | } else { | 76 | ctrl_outl(ctrl_inl(TMU0_TCNT), TMU0_TCOR); |
61 | printk("%s (): hardware timer problem?\n", | 77 | break; |
62 | __FUNCTION__); | 78 | case CLOCK_EVT_MODE_ONESHOT: |
63 | } | 79 | ctrl_outl(0, TMU0_TCOR); |
64 | } | 80 | break; |
65 | } else | 81 | case CLOCK_EVT_MODE_UNUSED: |
66 | jiffies_p = jiffies_t; | 82 | case CLOCK_EVT_MODE_SHUTDOWN: |
67 | 83 | break; | |
68 | count_p = count; | 84 | } |
69 | |||
70 | count = ((LATCH-1) - count) * TICK_SIZE; | ||
71 | count = (count + LATCH/2) / LATCH; | ||
72 | |||
73 | return count; | ||
74 | } | 85 | } |
75 | 86 | ||
87 | static struct clock_event_device tmu0_clockevent = { | ||
88 | .name = "tmu0", | ||
89 | .shift = 32, | ||
90 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
91 | .set_mode = tmu_set_mode, | ||
92 | .set_next_event = tmu_set_next_event, | ||
93 | }; | ||
94 | |||
76 | static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) | 95 | static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) |
77 | { | 96 | { |
97 | struct clock_event_device *evt = &tmu0_clockevent; | ||
78 | unsigned long timer_status; | 98 | unsigned long timer_status; |
79 | 99 | ||
80 | /* Clear UNF bit */ | 100 | /* Clear UNF bit */ |
@@ -82,72 +102,76 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) | |||
82 | timer_status &= ~0x100; | 102 | timer_status &= ~0x100; |
83 | ctrl_outw(timer_status, TMU0_TCR); | 103 | ctrl_outw(timer_status, TMU0_TCR); |
84 | 104 | ||
85 | /* | 105 | evt->event_handler(evt); |
86 | * Here we are in the timer irq handler. We just have irqs locally | ||
87 | * disabled but we don't know if the timer_bh is running on the other | ||
88 | * CPU. We need to avoid to SMP race with it. NOTE: we don' t need | ||
89 | * the irq version of write_lock because as just said we have irq | ||
90 | * locally disabled. -arca | ||
91 | */ | ||
92 | write_seqlock(&xtime_lock); | ||
93 | handle_timer_tick(); | ||
94 | write_sequnlock(&xtime_lock); | ||
95 | 106 | ||
96 | return IRQ_HANDLED; | 107 | return IRQ_HANDLED; |
97 | } | 108 | } |
98 | 109 | ||
99 | static struct irqaction tmu_irq = { | 110 | static struct irqaction tmu0_irq = { |
100 | .name = "timer", | 111 | .name = "periodic timer", |
101 | .handler = tmu_timer_interrupt, | 112 | .handler = tmu_timer_interrupt, |
102 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 113 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
103 | .mask = CPU_MASK_NONE, | 114 | .mask = CPU_MASK_NONE, |
104 | }; | 115 | }; |
105 | 116 | ||
106 | static void tmu_clk_init(struct clk *clk) | 117 | static void tmu0_clk_init(struct clk *clk) |
107 | { | 118 | { |
108 | u8 divisor = TMU0_TCR_INIT & 0x7; | 119 | u8 divisor = TMU_TCR_INIT & 0x7; |
109 | ctrl_outw(TMU0_TCR_INIT, TMU0_TCR); | 120 | ctrl_outw(TMU_TCR_INIT, TMU0_TCR); |
110 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); | 121 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); |
111 | } | 122 | } |
112 | 123 | ||
113 | static void tmu_clk_recalc(struct clk *clk) | 124 | static void tmu0_clk_recalc(struct clk *clk) |
114 | { | 125 | { |
115 | u8 divisor = ctrl_inw(TMU0_TCR) & 0x7; | 126 | u8 divisor = ctrl_inw(TMU0_TCR) & 0x7; |
116 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); | 127 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); |
117 | } | 128 | } |
118 | 129 | ||
119 | static struct clk_ops tmu_clk_ops = { | 130 | static struct clk_ops tmu0_clk_ops = { |
120 | .init = tmu_clk_init, | 131 | .init = tmu0_clk_init, |
121 | .recalc = tmu_clk_recalc, | 132 | .recalc = tmu0_clk_recalc, |
122 | }; | 133 | }; |
123 | 134 | ||
124 | static struct clk tmu0_clk = { | 135 | static struct clk tmu0_clk = { |
125 | .name = "tmu0_clk", | 136 | .name = "tmu0_clk", |
126 | .ops = &tmu_clk_ops, | 137 | .ops = &tmu0_clk_ops, |
127 | }; | 138 | }; |
128 | 139 | ||
129 | static int tmu_timer_start(void) | 140 | static void tmu1_clk_init(struct clk *clk) |
130 | { | 141 | { |
131 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | 142 | u8 divisor = TMU_TCR_INIT & 0x7; |
132 | return 0; | 143 | ctrl_outw(divisor, TMU1_TCR); |
144 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); | ||
133 | } | 145 | } |
134 | 146 | ||
135 | static int tmu_timer_stop(void) | 147 | static void tmu1_clk_recalc(struct clk *clk) |
136 | { | 148 | { |
137 | ctrl_outb(0, TMU_TSTR); | 149 | u8 divisor = ctrl_inw(TMU1_TCR) & 0x7; |
138 | return 0; | 150 | clk->rate = clk->parent->rate / (4 << (divisor << 1)); |
139 | } | 151 | } |
140 | 152 | ||
153 | static struct clk_ops tmu1_clk_ops = { | ||
154 | .init = tmu1_clk_init, | ||
155 | .recalc = tmu1_clk_recalc, | ||
156 | }; | ||
157 | |||
158 | static struct clk tmu1_clk = { | ||
159 | .name = "tmu1_clk", | ||
160 | .ops = &tmu1_clk_ops, | ||
161 | }; | ||
162 | |||
141 | static int tmu_timer_init(void) | 163 | static int tmu_timer_init(void) |
142 | { | 164 | { |
143 | unsigned long interval; | 165 | unsigned long interval; |
166 | unsigned long frequency; | ||
144 | 167 | ||
145 | setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq); | 168 | setup_irq(CONFIG_SH_TIMER_IRQ, &tmu0_irq); |
146 | 169 | ||
147 | tmu0_clk.parent = clk_get(NULL, "module_clk"); | 170 | tmu0_clk.parent = clk_get(NULL, "module_clk"); |
171 | tmu1_clk.parent = clk_get(NULL, "module_clk"); | ||
148 | 172 | ||
149 | /* Start TMU0 */ | ||
150 | tmu_timer_stop(); | 173 | tmu_timer_stop(); |
174 | |||
151 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \ | 175 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \ |
152 | !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ | 176 | !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ |
153 | !defined(CONFIG_CPU_SUBTYPE_SH7785) | 177 | !defined(CONFIG_CPU_SUBTYPE_SH7785) |
@@ -155,15 +179,29 @@ static int tmu_timer_init(void) | |||
155 | #endif | 179 | #endif |
156 | 180 | ||
157 | clk_register(&tmu0_clk); | 181 | clk_register(&tmu0_clk); |
182 | clk_register(&tmu1_clk); | ||
158 | clk_enable(&tmu0_clk); | 183 | clk_enable(&tmu0_clk); |
184 | clk_enable(&tmu1_clk); | ||
159 | 185 | ||
160 | interval = (clk_get_rate(&tmu0_clk) + HZ / 2) / HZ; | 186 | frequency = clk_get_rate(&tmu0_clk); |
161 | printk(KERN_INFO "Interval = %ld\n", interval); | 187 | interval = (frequency + HZ / 2) / HZ; |
162 | 188 | ||
163 | ctrl_outl(interval, TMU0_TCOR); | 189 | sh_hpt_frequency = clk_get_rate(&tmu1_clk); |
164 | ctrl_outl(interval, TMU0_TCNT); | 190 | ctrl_outl(~0, TMU1_TCNT); |
191 | ctrl_outl(~0, TMU1_TCOR); | ||
165 | 192 | ||
166 | tmu_timer_start(); | 193 | tmu0_timer_set_interval(interval, 1); |
194 | |||
195 | tmu0_clockevent.mult = div_sc(frequency, NSEC_PER_SEC, | ||
196 | tmu0_clockevent.shift); | ||
197 | tmu0_clockevent.max_delta_ns = | ||
198 | clockevent_delta2ns(-1, &tmu0_clockevent); | ||
199 | tmu0_clockevent.min_delta_ns = | ||
200 | clockevent_delta2ns(1, &tmu0_clockevent); | ||
201 | |||
202 | tmu0_clockevent.cpumask = cpumask_of_cpu(0); | ||
203 | |||
204 | clockevents_register_device(&tmu0_clockevent); | ||
167 | 205 | ||
168 | return 0; | 206 | return 0; |
169 | } | 207 | } |
@@ -172,9 +210,7 @@ struct sys_timer_ops tmu_timer_ops = { | |||
172 | .init = tmu_timer_init, | 210 | .init = tmu_timer_init, |
173 | .start = tmu_timer_start, | 211 | .start = tmu_timer_start, |
174 | .stop = tmu_timer_stop, | 212 | .stop = tmu_timer_stop, |
175 | #ifndef CONFIG_GENERIC_TIME | 213 | .read = tmu_timer_read, |
176 | .get_offset = tmu_timer_get_offset, | ||
177 | #endif | ||
178 | }; | 214 | }; |
179 | 215 | ||
180 | struct sys_timer tmu_timer = { | 216 | struct sys_timer tmu_timer = { |
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 7b40f0ff3dfc..3a197649cd83 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c | |||
@@ -20,10 +20,10 @@ | |||
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/bug.h> | 21 | #include <linux/bug.h> |
22 | #include <linux/debug_locks.h> | 22 | #include <linux/debug_locks.h> |
23 | #include <linux/kdebug.h> | ||
23 | #include <linux/limits.h> | 24 | #include <linux/limits.h> |
24 | #include <asm/system.h> | 25 | #include <asm/system.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | #include <asm/kdebug.h> | ||
27 | 27 | ||
28 | #ifdef CONFIG_SH_KGDB | 28 | #ifdef CONFIG_SH_KGDB |
29 | #include <asm/kgdb.h> | 29 | #include <asm/kgdb.h> |
@@ -76,20 +76,6 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) | |||
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
79 | ATOMIC_NOTIFIER_HEAD(shdie_chain); | ||
80 | |||
81 | int register_die_notifier(struct notifier_block *nb) | ||
82 | { | ||
83 | return atomic_notifier_chain_register(&shdie_chain, nb); | ||
84 | } | ||
85 | EXPORT_SYMBOL(register_die_notifier); | ||
86 | |||
87 | int unregister_die_notifier(struct notifier_block *nb) | ||
88 | { | ||
89 | return atomic_notifier_chain_unregister(&shdie_chain, nb); | ||
90 | } | ||
91 | EXPORT_SYMBOL(unregister_die_notifier); | ||
92 | |||
93 | static DEFINE_SPINLOCK(die_lock); | 79 | static DEFINE_SPINLOCK(die_lock); |
94 | 80 | ||
95 | void die(const char * str, struct pt_regs * regs, long err) | 81 | void die(const char * str, struct pt_regs * regs, long err) |
@@ -505,7 +491,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) | |||
505 | simple: | 491 | simple: |
506 | ret = handle_unaligned_ins(instruction,regs); | 492 | ret = handle_unaligned_ins(instruction,regs); |
507 | if (ret==0) | 493 | if (ret==0) |
508 | regs->pc += 2; | 494 | regs->pc += instruction_size(instruction); |
509 | return ret; | 495 | return ret; |
510 | } | 496 | } |
511 | #endif /* CONFIG_CPU_SH2A */ | 497 | #endif /* CONFIG_CPU_SH2A */ |
@@ -682,7 +668,7 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, | |||
682 | 668 | ||
683 | err = do_fpu_inst(inst, regs); | 669 | err = do_fpu_inst(inst, regs); |
684 | if (!err) { | 670 | if (!err) { |
685 | regs->pc += 2; | 671 | regs->pc += instruction_size(inst); |
686 | return; | 672 | return; |
687 | } | 673 | } |
688 | /* not a FPU inst. */ | 674 | /* not a FPU inst. */ |
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c index 7b0f66f03319..e146bafcd14f 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.c +++ b/arch/sh/kernel/vsyscall/vsyscall.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/vsyscall.c | 2 | * arch/sh/kernel/vsyscall/vsyscall.c |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Paul Mundt | 4 | * Copyright (C) 2006 Paul Mundt |
5 | * | 5 | * |
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c index 351714694d6d..f3ddd2133e6f 100644 --- a/arch/sh/lib/delay.c +++ b/arch/sh/lib/delay.c | |||
@@ -24,9 +24,10 @@ inline void __const_udelay(unsigned long xloops) | |||
24 | __asm__("dmulu.l %0, %2\n\t" | 24 | __asm__("dmulu.l %0, %2\n\t" |
25 | "sts mach, %0" | 25 | "sts mach, %0" |
26 | : "=r" (xloops) | 26 | : "=r" (xloops) |
27 | : "0" (xloops), "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy) | 27 | : "0" (xloops), |
28 | "r" (HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) | ||
28 | : "macl", "mach"); | 29 | : "macl", "mach"); |
29 | __delay(xloops * HZ); | 30 | __delay(xloops); |
30 | } | 31 | } |
31 | 32 | ||
32 | void __udelay(unsigned long usecs) | 33 | void __udelay(unsigned long usecs) |
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 12f3d394dc28..253346d7b316 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig | |||
@@ -218,6 +218,9 @@ endmenu | |||
218 | 218 | ||
219 | menu "Memory management options" | 219 | menu "Memory management options" |
220 | 220 | ||
221 | config QUICKLIST | ||
222 | def_bool y | ||
223 | |||
221 | config MMU | 224 | config MMU |
222 | bool "Support for memory management hardware" | 225 | bool "Support for memory management hardware" |
223 | depends on !CPU_SH2 | 226 | depends on !CPU_SH2 |
@@ -300,6 +303,10 @@ config NODES_SHIFT | |||
300 | config ARCH_FLATMEM_ENABLE | 303 | config ARCH_FLATMEM_ENABLE |
301 | def_bool y | 304 | def_bool y |
302 | 305 | ||
306 | config MAX_ACTIVE_REGIONS | ||
307 | int | ||
308 | default "1" | ||
309 | |||
303 | config ARCH_POPULATES_NODE_MAP | 310 | config ARCH_POPULATES_NODE_MAP |
304 | def_bool y | 311 | def_bool y |
305 | 312 | ||
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 0ecc117cade4..9207da67ff8a 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/hardirq.h> | 16 | #include <linux/hardirq.h> |
17 | #include <linux/kprobes.h> | 17 | #include <linux/kprobes.h> |
18 | #include <asm/kdebug.h> | 18 | #include <linux/kdebug.h> |
19 | #include <asm/system.h> | 19 | #include <asm/system.h> |
20 | #include <asm/mmu_context.h> | 20 | #include <asm/mmu_context.h> |
21 | #include <asm/tlbflush.h> | 21 | #include <asm/tlbflush.h> |
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 4d030988b368..8fe223a890ed 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c | |||
@@ -67,6 +67,8 @@ void show_mem(void) | |||
67 | printk("%d slab pages\n", slab); | 67 | printk("%d slab pages\n", slab); |
68 | printk("%d pages shared\n", shared); | 68 | printk("%d pages shared\n", shared); |
69 | printk("%d pages swap cached\n", cached); | 69 | printk("%d pages swap cached\n", cached); |
70 | printk(KERN_INFO "Total of %ld pages in page table cache\n", | ||
71 | quicklist_total_size()); | ||
70 | } | 72 | } |
71 | 73 | ||
72 | #ifdef CONFIG_MMU | 74 | #ifdef CONFIG_MMU |
diff --git a/arch/sparc/kernel/asm-offsets.c b/arch/sparc/kernel/asm-offsets.c index 29d7cfd1c970..6773ed76e414 100644 --- a/arch/sparc/kernel/asm-offsets.c +++ b/arch/sparc/kernel/asm-offsets.c | |||
@@ -28,7 +28,7 @@ int foo(void) | |||
28 | DEFINE(AOFF_task_gid, offsetof(struct task_struct, gid)); | 28 | DEFINE(AOFF_task_gid, offsetof(struct task_struct, gid)); |
29 | DEFINE(AOFF_task_euid, offsetof(struct task_struct, euid)); | 29 | DEFINE(AOFF_task_euid, offsetof(struct task_struct, euid)); |
30 | DEFINE(AOFF_task_egid, offsetof(struct task_struct, egid)); | 30 | DEFINE(AOFF_task_egid, offsetof(struct task_struct, egid)); |
31 | /* DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info)); */ | 31 | /* DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); */ |
32 | DEFINE(ASIZ_task_uid, sizeof(current->uid)); | 32 | DEFINE(ASIZ_task_uid, sizeof(current->uid)); |
33 | DEFINE(ASIZ_task_gid, sizeof(current->gid)); | 33 | DEFINE(ASIZ_task_gid, sizeof(current->gid)); |
34 | DEFINE(ASIZ_task_euid, sizeof(current->euid)); | 34 | DEFINE(ASIZ_task_euid, sizeof(current->euid)); |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index dc652f210290..d0fde36395b4 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/kdebug.h> | 20 | #include <linux/kdebug.h> |
21 | 21 | ||
22 | #include <asm/smp.h> | ||
22 | #include <asm/delay.h> | 23 | #include <asm/delay.h> |
23 | #include <asm/system.h> | 24 | #include <asm/system.h> |
24 | #include <asm/ptrace.h> | 25 | #include <asm/ptrace.h> |
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 354cc6b70530..b9c0f307a8fa 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig | |||
@@ -320,21 +320,7 @@ source "crypto/Kconfig" | |||
320 | 320 | ||
321 | source "lib/Kconfig" | 321 | source "lib/Kconfig" |
322 | 322 | ||
323 | menu "SCSI support" | 323 | source "drivers/scsi/Kconfig" |
324 | depends on BROKEN | ||
325 | |||
326 | config SCSI | ||
327 | tristate "SCSI support" | ||
328 | |||
329 | # This gives us free_dma, which scsi.c wants. | ||
330 | config GENERIC_ISA_DMA | ||
331 | bool | ||
332 | depends on SCSI | ||
333 | default y | ||
334 | |||
335 | source "arch/um/Kconfig.scsi" | ||
336 | |||
337 | endmenu | ||
338 | 324 | ||
339 | source "drivers/md/Kconfig" | 325 | source "drivers/md/Kconfig" |
340 | 326 | ||
diff --git a/arch/um/Kconfig.scsi b/arch/um/Kconfig.scsi deleted file mode 100644 index c291c942b1a8..000000000000 --- a/arch/um/Kconfig.scsi +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | comment "SCSI support type (disk, tape, CD-ROM)" | ||
2 | depends on SCSI | ||
3 | |||
4 | config BLK_DEV_SD | ||
5 | tristate "SCSI disk support" | ||
6 | depends on SCSI | ||
7 | |||
8 | config SD_EXTRA_DEVS | ||
9 | int "Maximum number of SCSI disks that can be loaded as modules" | ||
10 | depends on BLK_DEV_SD | ||
11 | default "40" | ||
12 | |||
13 | config CHR_DEV_ST | ||
14 | tristate "SCSI tape support" | ||
15 | depends on SCSI | ||
16 | |||
17 | config BLK_DEV_SR | ||
18 | tristate "SCSI CD-ROM support" | ||
19 | depends on SCSI | ||
20 | |||
21 | config BLK_DEV_SR_VENDOR | ||
22 | bool "Enable vendor-specific extensions (for SCSI CDROM)" | ||
23 | depends on BLK_DEV_SR | ||
24 | |||
25 | config SR_EXTRA_DEVS | ||
26 | int "Maximum number of CDROM devices that can be loaded as modules" | ||
27 | depends on BLK_DEV_SR | ||
28 | default "2" | ||
29 | |||
30 | config CHR_DEV_SG | ||
31 | tristate "SCSI generic support" | ||
32 | depends on SCSI | ||
33 | |||
34 | comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs" | ||
35 | depends on SCSI | ||
36 | |||
37 | #if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then | ||
38 | config SCSI_DEBUG_QUEUES | ||
39 | bool "Enable extra checks in new queueing code" | ||
40 | depends on SCSI | ||
41 | |||
42 | #fi | ||
43 | config SCSI_MULTI_LUN | ||
44 | bool "Probe all LUNs on each SCSI device" | ||
45 | depends on SCSI | ||
46 | |||
47 | config SCSI_CONSTANTS | ||
48 | bool "Verbose SCSI error reporting (kernel size +=12K)" | ||
49 | depends on SCSI | ||
50 | |||
51 | config SCSI_LOGGING | ||
52 | bool "SCSI logging facility" | ||
53 | depends on SCSI | ||
54 | |||
55 | config SCSI_DEBUG | ||
56 | tristate "SCSI debugging host simulator (EXPERIMENTAL)" | ||
57 | depends on SCSI | ||
58 | |||
diff --git a/arch/um/include/sysdep-i386/archsetjmp.h b/arch/um/include/sysdep-i386/archsetjmp.h index 11bafab669e9..0f312085ce1d 100644 --- a/arch/um/include/sysdep-i386/archsetjmp.h +++ b/arch/um/include/sysdep-i386/archsetjmp.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/i386/include/klibc/archsetjmp.h | 2 | * arch/um/include/sysdep-i386/archsetjmp.h |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef _KLIBC_ARCHSETJMP_H | 5 | #ifndef _KLIBC_ARCHSETJMP_H |
diff --git a/arch/um/include/sysdep-x86_64/archsetjmp.h b/arch/um/include/sysdep-x86_64/archsetjmp.h index 9a5e1a6ec800..2af8f12ca161 100644 --- a/arch/um/include/sysdep-x86_64/archsetjmp.h +++ b/arch/um/include/sysdep-x86_64/archsetjmp.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/x86_64/include/klibc/archsetjmp.h | 2 | * arch/um/include/sysdep-x86_64/archsetjmp.h |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef _KLIBC_ARCHSETJMP_H | 5 | #ifndef _KLIBC_ARCHSETJMP_H |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index ef36facd8fe9..a96ae1a0610e 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -178,20 +178,23 @@ int start_uml_skas(void) | |||
178 | 178 | ||
179 | int external_pid_skas(struct task_struct *task) | 179 | int external_pid_skas(struct task_struct *task) |
180 | { | 180 | { |
181 | #warning Need to look up userspace_pid by cpu | 181 | /* FIXME: Need to look up userspace_pid by cpu */ |
182 | return(userspace_pid[0]); | 182 | return(userspace_pid[0]); |
183 | } | 183 | } |
184 | 184 | ||
185 | int thread_pid_skas(struct task_struct *task) | 185 | int thread_pid_skas(struct task_struct *task) |
186 | { | 186 | { |
187 | #warning Need to look up userspace_pid by cpu | 187 | /* FIXME: Need to look up userspace_pid by cpu */ |
188 | return(userspace_pid[0]); | 188 | return(userspace_pid[0]); |
189 | } | 189 | } |
190 | 190 | ||
191 | void kill_off_processes_skas(void) | 191 | void kill_off_processes_skas(void) |
192 | { | 192 | { |
193 | if(proc_mm) | 193 | if(proc_mm) |
194 | #warning need to loop over userspace_pids in kill_off_processes_skas | 194 | /* |
195 | * FIXME: need to loop over userspace_pids in | ||
196 | * kill_off_processes_skas | ||
197 | */ | ||
195 | os_kill_ptraced_process(userspace_pid[0], 1); | 198 | os_kill_ptraced_process(userspace_pid[0], 1); |
196 | else { | 199 | else { |
197 | struct task_struct *p; | 200 | struct task_struct *p; |
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 92a7b59120d6..2d9d2ca39299 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -239,6 +239,7 @@ out: | |||
239 | return ok; | 239 | return ok; |
240 | } | 240 | } |
241 | 241 | ||
242 | #ifdef UML_CONFIG_MODE_TT | ||
242 | void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) | 243 | void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) |
243 | { | 244 | { |
244 | int flags = 0, pages; | 245 | int flags = 0, pages; |
@@ -260,6 +261,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) | |||
260 | "errno = %d\n", errno); | 261 | "errno = %d\n", errno); |
261 | } | 262 | } |
262 | } | 263 | } |
264 | #endif | ||
263 | 265 | ||
264 | void init_new_thread_signals(void) | 266 | void init_new_thread_signals(void) |
265 | { | 267 | { |
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 8e490fff3d47..5c8946320799 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c | |||
@@ -68,7 +68,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | |||
68 | int err, pid = mm_idp->u.pid; | 68 | int err, pid = mm_idp->u.pid; |
69 | 69 | ||
70 | if(proc_mm) | 70 | if(proc_mm) |
71 | #warning Need to look up userspace_pid by cpu | 71 | /* FIXME: Need to look up userspace_pid by cpu */ |
72 | pid = userspace_pid[0]; | 72 | pid = userspace_pid[0]; |
73 | 73 | ||
74 | multi_count++; | 74 | multi_count++; |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 5c088a55396c..6a0e466d01e3 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -586,7 +586,7 @@ void switch_mm_skas(struct mm_id *mm_idp) | |||
586 | { | 586 | { |
587 | int err; | 587 | int err; |
588 | 588 | ||
589 | #warning need cpu pid in switch_mm_skas | 589 | /* FIXME: need cpu pid in switch_mm_skas */ |
590 | if(proc_mm){ | 590 | if(proc_mm){ |
591 | err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, | 591 | err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, |
592 | mm_idp->u.mm_fd); | 592 | mm_idp->u.mm_fd); |
diff --git a/arch/v850/kernel/asm-offsets.c b/arch/v850/kernel/asm-offsets.c index 24f291369070..cee5c3142d41 100644 --- a/arch/v850/kernel/asm-offsets.c +++ b/arch/v850/kernel/asm-offsets.c | |||
@@ -29,7 +29,7 @@ int main (void) | |||
29 | DEFINE (TASK_PTRACE, offsetof (struct task_struct, ptrace)); | 29 | DEFINE (TASK_PTRACE, offsetof (struct task_struct, ptrace)); |
30 | DEFINE (TASK_BLOCKED, offsetof (struct task_struct, blocked)); | 30 | DEFINE (TASK_BLOCKED, offsetof (struct task_struct, blocked)); |
31 | DEFINE (TASK_THREAD, offsetof (struct task_struct, thread)); | 31 | DEFINE (TASK_THREAD, offsetof (struct task_struct, thread)); |
32 | DEFINE (TASK_THREAD_INFO, offsetof (struct task_struct, thread_info)); | 32 | DEFINE (TASK_THREAD_INFO, offsetof (struct task_struct, stack)); |
33 | DEFINE (TASK_MM, offsetof (struct task_struct, mm)); | 33 | DEFINE (TASK_MM, offsetof (struct task_struct, mm)); |
34 | DEFINE (TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm)); | 34 | DEFINE (TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm)); |
35 | DEFINE (TASK_PID, offsetof (struct task_struct, pid)); | 35 | DEFINE (TASK_PID, offsetof (struct task_struct, pid)); |
diff --git a/arch/v850/kernel/entry.S b/arch/v850/kernel/entry.S index 8bc521ca081f..e4327a8d6bcd 100644 --- a/arch/v850/kernel/entry.S +++ b/arch/v850/kernel/entry.S | |||
@@ -523,7 +523,7 @@ END(ret_from_trap) | |||
523 | 523 | ||
524 | 524 | ||
525 | /* This the initial entry point for a new child thread, with an appropriate | 525 | /* This the initial entry point for a new child thread, with an appropriate |
526 | stack in place that makes it look the the child is in the middle of an | 526 | stack in place that makes it look that the child is in the middle of an |
527 | syscall. This function is actually `returned to' from switch_thread | 527 | syscall. This function is actually `returned to' from switch_thread |
528 | (copy_thread makes ret_from_fork the return address in each new thread's | 528 | (copy_thread makes ret_from_fork the return address in each new thread's |
529 | saved context). */ | 529 | saved context). */ |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 4d582589fa89..d8bfe315471c 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -1413,7 +1413,7 @@ static void ack_apic_level(unsigned int irq) | |||
1413 | 1413 | ||
1414 | /* | 1414 | /* |
1415 | * We must acknowledge the irq before we move it or the acknowledge will | 1415 | * We must acknowledge the irq before we move it or the acknowledge will |
1416 | * not propogate properly. | 1416 | * not propagate properly. |
1417 | */ | 1417 | */ |
1418 | ack_APIC_irq(); | 1418 | ack_APIC_irq(); |
1419 | 1419 | ||
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index 3bc30d2c13d3..3eaceac32481 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
@@ -32,7 +32,7 @@ atomic_t irq_err_count; | |||
32 | */ | 32 | */ |
33 | static inline void stack_overflow_check(struct pt_regs *regs) | 33 | static inline void stack_overflow_check(struct pt_regs *regs) |
34 | { | 34 | { |
35 | u64 curbase = (u64) current->thread_info; | 35 | u64 curbase = (u64)task_stack_page(current); |
36 | static unsigned long warned = -60*HZ; | 36 | static unsigned long warned = -60*HZ; |
37 | 37 | ||
38 | if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && | 38 | if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 442169640e45..a14375dd5425 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -720,9 +720,11 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
720 | 720 | ||
721 | switch (action) { | 721 | switch (action) { |
722 | case CPU_ONLINE: | 722 | case CPU_ONLINE: |
723 | case CPU_ONLINE_FROZEN: | ||
723 | mce_create_device(cpu); | 724 | mce_create_device(cpu); |
724 | break; | 725 | break; |
725 | case CPU_DEAD: | 726 | case CPU_DEAD: |
727 | case CPU_DEAD_FROZEN: | ||
726 | mce_remove_device(cpu); | 728 | mce_remove_device(cpu); |
727 | break; | 729 | break; |
728 | } | 730 | } |
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c index d0bd5d66e103..03356e64f9c8 100644 --- a/arch/x86_64/kernel/mce_amd.c +++ b/arch/x86_64/kernel/mce_amd.c | |||
@@ -654,9 +654,11 @@ static int threshold_cpu_callback(struct notifier_block *nfb, | |||
654 | 654 | ||
655 | switch (action) { | 655 | switch (action) { |
656 | case CPU_ONLINE: | 656 | case CPU_ONLINE: |
657 | case CPU_ONLINE_FROZEN: | ||
657 | threshold_create_device(cpu); | 658 | threshold_create_device(cpu); |
658 | break; | 659 | break; |
659 | case CPU_DEAD: | 660 | case CPU_DEAD: |
661 | case CPU_DEAD_FROZEN: | ||
660 | threshold_remove_device(cpu); | 662 | threshold_remove_device(cpu); |
661 | break; | 663 | break; |
662 | default: | 664 | default: |
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index dc32cef96195..51d4c6fa88c8 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c | |||
@@ -327,7 +327,7 @@ static int __cpuinit | |||
327 | cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) | 327 | cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) |
328 | { | 328 | { |
329 | long cpu = (long)arg; | 329 | long cpu = (long)arg; |
330 | if (action == CPU_ONLINE) | 330 | if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) |
331 | smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); | 331 | smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); |
332 | return NOTIFY_DONE; | 332 | return NOTIFY_DONE; |
333 | } | 333 | } |
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index b256cfbef344..698079b3a336 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c | |||
@@ -70,7 +70,7 @@ int main(void) | |||
70 | DEFINE(TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm)); | 70 | DEFINE(TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm)); |
71 | DEFINE(TASK_PID, offsetof (struct task_struct, pid)); | 71 | DEFINE(TASK_PID, offsetof (struct task_struct, pid)); |
72 | DEFINE(TASK_THREAD, offsetof (struct task_struct, thread)); | 72 | DEFINE(TASK_THREAD, offsetof (struct task_struct, thread)); |
73 | DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, thread_info)); | 73 | DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, stack)); |
74 | DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct)); | 74 | DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct)); |
75 | BLANK(); | 75 | BLANK(); |
76 | 76 | ||
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index ca76f071666e..f5319d78c876 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/xtensa/pci-dma.c | 2 | * arch/xtensa/kernel/pci-dma.c |
3 | * | 3 | * |
4 | * DMA coherent memory allocation. | 4 | * DMA coherent memory allocation. |
5 | * | 5 | * |