aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 11:13:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 11:13:35 -0500
commitadf9904dc774f23f04a5425f0198483ea61f878b (patch)
treedfe0527c7f3877eb4d155ddb20fd303c1d8328c0
parentbb592cf474404e51cbf3c419fb72fda83c4b7d72 (diff)
parent49966bae8446f5ba7e8afbd01bde82af4e00628a (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k: m68k: parport_mfc3 - Not makes it a bool before the comparison. m68k: don't export static inline functions fbdev: atafb - add palette register check m68k: Remove the BKL from sys_execve m68k: Cleanup linker scripts using new linker script macros. m68k: Make thread_info.h usable from assembly. m68knommu: define arch_has_single_step() and friends m68k: ptrace fixes m68k: use generic code for ptrace requests rtc: Add an RTC driver for the Ricoh RP5C01 rtc: Add an RTC driver for the Oki MSM6242
-rw-r--r--arch/m68k/include/asm/ptrace.h17
-rw-r--r--arch/m68k/include/asm/thread_info_mm.h5
-rw-r--r--arch/m68k/kernel/entry.S6
-rw-r--r--arch/m68k/kernel/process.c5
-rw-r--r--arch/m68k/kernel/ptrace.c112
-rw-r--r--arch/m68k/kernel/vmlinux-std.lds61
-rw-r--r--arch/m68k/kernel/vmlinux-sun3.lds54
-rw-r--r--arch/m68knommu/kernel/ptrace.c18
-rw-r--r--drivers/dio/dio-driver.c1
-rw-r--r--drivers/parport/parport_mfc3.c2
-rw-r--r--drivers/rtc/Kconfig19
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-msm6242.c269
-rw-r--r--drivers/rtc/rtc-rp5c01.c222
-rw-r--r--drivers/video/atafb.c3
-rw-r--r--drivers/zorro/zorro-driver.c1
16 files changed, 624 insertions, 173 deletions
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index 8c9194b98548..a6ab663bcc2e 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -71,6 +71,8 @@ struct switch_stack {
71#define PTRACE_GETFPREGS 14 71#define PTRACE_GETFPREGS 14
72#define PTRACE_SETFPREGS 15 72#define PTRACE_SETFPREGS 15
73 73
74#define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */
75
74#ifdef __KERNEL__ 76#ifdef __KERNEL__
75 77
76#ifndef PS_S 78#ifndef PS_S
@@ -82,6 +84,21 @@ struct switch_stack {
82#define instruction_pointer(regs) ((regs)->pc) 84#define instruction_pointer(regs) ((regs)->pc)
83#define profile_pc(regs) instruction_pointer(regs) 85#define profile_pc(regs) instruction_pointer(regs)
84extern void show_regs(struct pt_regs *); 86extern void show_regs(struct pt_regs *);
87
88/*
89 * These are defined as per linux/ptrace.h, which see.
90 */
91struct task_struct;
92
93#define arch_has_single_step() (1)
94extern void user_enable_single_step(struct task_struct *);
95extern void user_disable_single_step(struct task_struct *);
96
97#ifdef CONFIG_MMU
98#define arch_has_block_step() (1)
99extern void user_enable_block_step(struct task_struct *);
100#endif
101
85#endif /* __KERNEL__ */ 102#endif /* __KERNEL__ */
86#endif /* __ASSEMBLY__ */ 103#endif /* __ASSEMBLY__ */
87#endif /* _M68K_PTRACE_H */ 104#endif /* _M68K_PTRACE_H */
diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h
index b6da3882be9b..167e518db41b 100644
--- a/arch/m68k/include/asm/thread_info_mm.h
+++ b/arch/m68k/include/asm/thread_info_mm.h
@@ -4,10 +4,12 @@
4#ifndef ASM_OFFSETS_C 4#ifndef ASM_OFFSETS_C
5#include <asm/asm-offsets.h> 5#include <asm/asm-offsets.h>
6#endif 6#endif
7#include <asm/current.h>
8#include <asm/types.h> 7#include <asm/types.h>
9#include <asm/page.h> 8#include <asm/page.h>
10 9
10#ifndef __ASSEMBLY__
11#include <asm/current.h>
12
11struct thread_info { 13struct thread_info {
12 struct task_struct *task; /* main task structure */ 14 struct task_struct *task; /* main task structure */
13 unsigned long flags; 15 unsigned long flags;
@@ -16,6 +18,7 @@ struct thread_info {
16 __u32 cpu; /* should always be 0 on m68k */ 18 __u32 cpu; /* should always be 0 on m68k */
17 struct restart_block restart_block; 19 struct restart_block restart_block;
18}; 20};
21#endif /* __ASSEMBLY__ */
19 22
20#define PREEMPT_ACTIVE 0x4000000 23#define PREEMPT_ACTIVE 0x4000000
21 24
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index c5b33634c980..77fc7c16bf48 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -179,7 +179,11 @@ do_signal_return:
179 addql #8,%sp 179 addql #8,%sp
180 RESTORE_SWITCH_STACK 180 RESTORE_SWITCH_STACK
181 addql #4,%sp 181 addql #4,%sp
182 jbra resume_userspace 182 tstl %d0
183 jeq resume_userspace
184 | when single stepping into handler stop at the first insn
185 btst #6,%curptr@(TASK_INFO+TINFO_FLAGS+2)
186 jeq resume_userspace
183 187
184do_delayed_trace: 188do_delayed_trace:
185 bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR 189 bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 41230c595a8e..05296593e718 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -317,15 +317,12 @@ asmlinkage int sys_execve(char __user *name, char __user * __user *argv, char __
317 char * filename; 317 char * filename;
318 struct pt_regs *regs = (struct pt_regs *) &name; 318 struct pt_regs *regs = (struct pt_regs *) &name;
319 319
320 lock_kernel();
321 filename = getname(name); 320 filename = getname(name);
322 error = PTR_ERR(filename); 321 error = PTR_ERR(filename);
323 if (IS_ERR(filename)) 322 if (IS_ERR(filename))
324 goto out; 323 return error;
325 error = do_execve(filename, argv, envp, regs); 324 error = do_execve(filename, argv, envp, regs);
326 putname(filename); 325 putname(filename);
327out:
328 unlock_kernel();
329 return error; 326 return error;
330} 327}
331 328
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 2075543c2d92..1fc217e5f06b 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -35,7 +35,9 @@
35#define SR_MASK 0x001f 35#define SR_MASK 0x001f
36 36
37/* sets the trace bits. */ 37/* sets the trace bits. */
38#define TRACE_BITS 0x8000 38#define TRACE_BITS 0xC000
39#define T1_BIT 0x8000
40#define T0_BIT 0x4000
39 41
40/* Find the stack offset for a register, relative to thread.esp0. */ 42/* Find the stack offset for a register, relative to thread.esp0. */
41#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) 43#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
@@ -44,7 +46,7 @@
44/* Mapping from PT_xxx to the stack offset at which the register is 46/* Mapping from PT_xxx to the stack offset at which the register is
45 saved. Notice that usp has no stack-slot and needs to be treated 47 saved. Notice that usp has no stack-slot and needs to be treated
46 specially (see get_reg/put_reg below). */ 48 specially (see get_reg/put_reg below). */
47static int regoff[] = { 49static const int regoff[] = {
48 [0] = PT_REG(d1), 50 [0] = PT_REG(d1),
49 [1] = PT_REG(d2), 51 [1] = PT_REG(d2),
50 [2] = PT_REG(d3), 52 [2] = PT_REG(d3),
@@ -79,6 +81,14 @@ static inline long get_reg(struct task_struct *task, int regno)
79 addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); 81 addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
80 else 82 else
81 return 0; 83 return 0;
84 /* Need to take stkadj into account. */
85 if (regno == PT_SR || regno == PT_PC) {
86 long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
87 addr = (unsigned long *) ((unsigned long)addr + stkadj);
88 /* The sr is actually a 16 bit register. */
89 if (regno == PT_SR)
90 return *(unsigned short *)addr;
91 }
82 return *addr; 92 return *addr;
83} 93}
84 94
@@ -96,6 +106,16 @@ static inline int put_reg(struct task_struct *task, int regno,
96 addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); 106 addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
97 else 107 else
98 return -1; 108 return -1;
109 /* Need to take stkadj into account. */
110 if (regno == PT_SR || regno == PT_PC) {
111 long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
112 addr = (unsigned long *) ((unsigned long)addr + stkadj);
113 /* The sr is actually a 16 bit register. */
114 if (regno == PT_SR) {
115 *(unsigned short *)addr = data;
116 return 0;
117 }
118 }
99 *addr = data; 119 *addr = data;
100 return 0; 120 return 0;
101} 121}
@@ -105,7 +125,7 @@ static inline int put_reg(struct task_struct *task, int regno,
105 */ 125 */
106static inline void singlestep_disable(struct task_struct *child) 126static inline void singlestep_disable(struct task_struct *child)
107{ 127{
108 unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); 128 unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
109 put_reg(child, PT_SR, tmp); 129 put_reg(child, PT_SR, tmp);
110 clear_tsk_thread_flag(child, TIF_DELAYED_TRACE); 130 clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
111} 131}
@@ -118,18 +138,30 @@ void ptrace_disable(struct task_struct *child)
118 singlestep_disable(child); 138 singlestep_disable(child);
119} 139}
120 140
141void user_enable_single_step(struct task_struct *child)
142{
143 unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
144 put_reg(child, PT_SR, tmp | T1_BIT);
145 set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
146}
147
148void user_enable_block_step(struct task_struct *child)
149{
150 unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
151 put_reg(child, PT_SR, tmp | T0_BIT);
152}
153
154void user_disable_single_step(struct task_struct *child)
155{
156 singlestep_disable(child);
157}
158
121long arch_ptrace(struct task_struct *child, long request, long addr, long data) 159long arch_ptrace(struct task_struct *child, long request, long addr, long data)
122{ 160{
123 unsigned long tmp; 161 unsigned long tmp;
124 int i, ret = 0; 162 int i, ret = 0;
125 163
126 switch (request) { 164 switch (request) {
127 /* when I and D space are separate, these will need to be fixed. */
128 case PTRACE_PEEKTEXT: /* read word at location addr. */
129 case PTRACE_PEEKDATA:
130 ret = generic_ptrace_peekdata(child, addr, data);
131 break;
132
133 /* read the word at location addr in the USER area. */ 165 /* read the word at location addr in the USER area. */
134 case PTRACE_PEEKUSR: 166 case PTRACE_PEEKUSR:
135 if (addr & 3) 167 if (addr & 3)
@@ -138,8 +170,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
138 170
139 if (addr >= 0 && addr < 19) { 171 if (addr >= 0 && addr < 19) {
140 tmp = get_reg(child, addr); 172 tmp = get_reg(child, addr);
141 if (addr == PT_SR)
142 tmp >>= 16;
143 } else if (addr >= 21 && addr < 49) { 173 } else if (addr >= 21 && addr < 49) {
144 tmp = child->thread.fp[addr - 21]; 174 tmp = child->thread.fp[addr - 21];
145 /* Convert internal fpu reg representation 175 /* Convert internal fpu reg representation
@@ -149,16 +179,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
149 tmp = ((tmp & 0xffff0000) << 15) | 179 tmp = ((tmp & 0xffff0000) << 15) |
150 ((tmp & 0x0000ffff) << 16); 180 ((tmp & 0x0000ffff) << 16);
151 } else 181 } else
152 break; 182 goto out_eio;
153 ret = put_user(tmp, (unsigned long *)data); 183 ret = put_user(tmp, (unsigned long *)data);
154 break; 184 break;
155 185
156 /* when I and D space are separate, this will have to be fixed. */
157 case PTRACE_POKETEXT: /* write the word at location addr. */
158 case PTRACE_POKEDATA:
159 ret = generic_ptrace_pokedata(child, addr, data);
160 break;
161
162 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 186 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
163 if (addr & 3) 187 if (addr & 3)
164 goto out_eio; 188 goto out_eio;
@@ -166,9 +190,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
166 190
167 if (addr == PT_SR) { 191 if (addr == PT_SR) {
168 data &= SR_MASK; 192 data &= SR_MASK;
169 data <<= 16; 193 data |= get_reg(child, PT_SR) & ~SR_MASK;
170 data |= get_reg(child, PT_SR) & ~(SR_MASK << 16); 194 }
171 } else if (addr >= 0 && addr < 19) { 195 if (addr >= 0 && addr < 19) {
172 if (put_reg(child, addr, data)) 196 if (put_reg(child, addr, data))
173 goto out_eio; 197 goto out_eio;
174 } else if (addr >= 21 && addr < 48) { 198 } else if (addr >= 21 && addr < 48) {
@@ -185,52 +209,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
185 goto out_eio; 209 goto out_eio;
186 break; 210 break;
187 211
188 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
189 case PTRACE_CONT: /* restart after signal. */
190 if (!valid_signal(data))
191 goto out_eio;
192
193 if (request == PTRACE_SYSCALL)
194 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
195 else
196 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
197 child->exit_code = data;
198 singlestep_disable(child);
199 wake_up_process(child);
200 break;
201
202 /*
203 * make the child exit. Best I can do is send it a sigkill.
204 * perhaps it should be put in the status that it wants to
205 * exit.
206 */
207 case PTRACE_KILL:
208 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
209 break;
210 child->exit_code = SIGKILL;
211 singlestep_disable(child);
212 wake_up_process(child);
213 break;
214
215 case PTRACE_SINGLESTEP: /* set the trap flag. */
216 if (!valid_signal(data))
217 goto out_eio;
218
219 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
220 tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
221 put_reg(child, PT_SR, tmp);
222 set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
223
224 child->exit_code = data;
225 /* give it a chance to run. */
226 wake_up_process(child);
227 break;
228
229 case PTRACE_GETREGS: /* Get all gp regs from the child. */ 212 case PTRACE_GETREGS: /* Get all gp regs from the child. */
230 for (i = 0; i < 19; i++) { 213 for (i = 0; i < 19; i++) {
231 tmp = get_reg(child, i); 214 tmp = get_reg(child, i);
232 if (i == PT_SR)
233 tmp >>= 16;
234 ret = put_user(tmp, (unsigned long *)data); 215 ret = put_user(tmp, (unsigned long *)data);
235 if (ret) 216 if (ret)
236 break; 217 break;
@@ -245,8 +226,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
245 break; 226 break;
246 if (i == PT_SR) { 227 if (i == PT_SR) {
247 tmp &= SR_MASK; 228 tmp &= SR_MASK;
248 tmp <<= 16; 229 tmp |= get_reg(child, PT_SR) & ~SR_MASK;
249 tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
250 } 230 }
251 put_reg(child, i, tmp); 231 put_reg(child, i, tmp);
252 data += sizeof(long); 232 data += sizeof(long);
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 47eac19e8f61..878be5f38cad 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -2,6 +2,7 @@
2 2
3#include <asm-generic/vmlinux.lds.h> 3#include <asm-generic/vmlinux.lds.h>
4#include <asm/page.h> 4#include <asm/page.h>
5#include <asm/thread_info.h>
5 6
6OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") 7OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
7OUTPUT_ARCH(m68k) 8OUTPUT_ARCH(m68k)
@@ -22,73 +23,37 @@ SECTIONS
22 23
23 _etext = .; /* End of text section */ 24 _etext = .; /* End of text section */
24 25
25 . = ALIGN(16); /* Exception table */ 26 EXCEPTION_TABLE(16)
26 __start___ex_table = .;
27 __ex_table : { *(__ex_table) }
28 __stop___ex_table = .;
29 27
30 RODATA 28 RODATA
31 29
32 .data : { /* Data */ 30 RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
33 DATA_DATA
34 CONSTRUCTORS
35 }
36 31
37 . = ALIGN(16); 32 BSS_SECTION(0, 0, 0)
38 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
39
40 .bss : { *(.bss) } /* BSS */
41 33
42 _edata = .; /* End of data section */ 34 _edata = .; /* End of data section */
43 35
44 /* will be freed after init */ 36 /* will be freed after init */
45 . = ALIGN(PAGE_SIZE); /* Init code and data */ 37 . = ALIGN(PAGE_SIZE); /* Init code and data */
46 __init_begin = .; 38 __init_begin = .;
47 .init.text : { 39 INIT_TEXT_SECTION(PAGE_SIZE) :data
48 _sinittext = .; 40 INIT_DATA_SECTION(16)
49 INIT_TEXT
50 _einittext = .;
51 } :data
52 .init.data : { INIT_DATA }
53 . = ALIGN(16);
54 __setup_start = .;
55 .init.setup : { *(.init.setup) }
56 __setup_end = .;
57 __initcall_start = .;
58 .initcall.init : {
59 INITCALLS
60 }
61 __initcall_end = .;
62 __con_initcall_start = .;
63 .con_initcall.init : { *(.con_initcall.init) }
64 __con_initcall_end = .;
65 .m68k_fixup : { 41 .m68k_fixup : {
66 __start_fixup = .; 42 __start_fixup = .;
67 *(.m68k_fixup) 43 *(.m68k_fixup)
68 __stop_fixup = .; 44 __stop_fixup = .;
69 } 45 }
70 SECURITY_INIT
71#ifdef CONFIG_BLK_DEV_INITRD
72 . = ALIGN(8192);
73 __initramfs_start = .;
74 .init.ramfs : { *(.init.ramfs) }
75 __initramfs_end = .;
76#endif
77 NOTES 46 NOTES
78 . = ALIGN(8192); 47 .init_end : {
79 __init_end = .; 48 /* This ALIGN be in a section so that _end is at the end of the
80 49 load segment. */
81 .data.init_task : { *(.data.init_task) } /* The initial task and kernel stack */ 50 . = ALIGN(PAGE_SIZE);
51 __init_end = .;
52 }
82 53
83 _end = . ; 54 _end = . ;
84 55
85 /* Stabs debugging sections. */ 56 STABS_DEBUG
86 .stab 0 : { *(.stab) }
87 .stabstr 0 : { *(.stabstr) }
88 .stab.excl 0 : { *(.stab.excl) }
89 .stab.exclstr 0 : { *(.stab.exclstr) }
90 .stab.index 0 : { *(.stab.index) }
91 .stab.indexstr 0 : { *(.stab.indexstr) }
92 .comment 0 : { *(.comment) } 57 .comment 0 : { *(.comment) }
93 58
94 /* Sections to be discarded */ 59 /* Sections to be discarded */
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 03efaf04d7d7..1ad6b7ad2c17 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -2,6 +2,7 @@
2 2
3#include <asm-generic/vmlinux.lds.h> 3#include <asm-generic/vmlinux.lds.h>
4#include <asm/page.h> 4#include <asm/page.h>
5#include <asm/thread_info.h>
5 6
6OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k") 7OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
7OUTPUT_ARCH(m68k) 8OUTPUT_ARCH(m68k)
@@ -23,14 +24,8 @@ SECTIONS
23 24
24 _etext = .; /* End of text section */ 25 _etext = .; /* End of text section */
25 26
26 .data : { /* Data */ 27 EXCEPTION_TABLE(16) :data
27 DATA_DATA 28 RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) :data
28 CONSTRUCTORS
29 . = ALIGN(16); /* Exception table */
30 __start___ex_table = .;
31 *(__ex_table)
32 __stop___ex_table = .;
33 } :data
34 /* End of data goes *here* so that freeing init code works properly. */ 29 /* End of data goes *here* so that freeing init code works properly. */
35 _edata = .; 30 _edata = .;
36 NOTES 31 NOTES
@@ -38,56 +33,21 @@ SECTIONS
38 /* will be freed after init */ 33 /* will be freed after init */
39 . = ALIGN(PAGE_SIZE); /* Init code and data */ 34 . = ALIGN(PAGE_SIZE); /* Init code and data */
40__init_begin = .; 35__init_begin = .;
41 .init.text : { 36 INIT_TEXT_SECTION(PAGE_SIZE)
42 _sinittext = .; 37 INIT_DATA_SECTION(16)
43 INIT_TEXT
44 _einittext = .;
45 }
46 .init.data : { INIT_DATA }
47 . = ALIGN(16);
48 __setup_start = .;
49 .init.setup : { *(.init.setup) }
50 __setup_end = .;
51 __initcall_start = .;
52 .initcall.init : {
53 INITCALLS
54 }
55 __initcall_end = .;
56 __con_initcall_start = .;
57 .con_initcall.init : { *(.con_initcall.init) }
58 __con_initcall_end = .;
59 .m68k_fixup : { 38 .m68k_fixup : {
60 __start_fixup = .; 39 __start_fixup = .;
61 *(.m68k_fixup) 40 *(.m68k_fixup)
62 __stop_fixup = .; 41 __stop_fixup = .;
63 } 42 }
64 SECURITY_INIT
65#ifdef CONFIG_BLK_DEV_INITRD
66 . = ALIGN(PAGE_SIZE);
67 __initramfs_start = .;
68 .init.ramfs : { *(.init.ramfs) }
69 __initramfs_end = .;
70#endif
71 . = ALIGN(PAGE_SIZE); 43 . = ALIGN(PAGE_SIZE);
72 __init_end = .; 44 __init_end = .;
73 .data.init.task : { *(.data.init_task) }
74
75 45
76 .bss : { *(.bss) } /* BSS */ 46 BSS_SECTION(0, 0, 0)
77 47
78 _end = . ; 48 _end = . ;
79 49
80 .crap : { 50 STABS_DEBUG
81 /* Stabs debugging sections. */
82 *(.stab)
83 *(.stabstr)
84 *(.stab.excl)
85 *(.stab.exclstr)
86 *(.stab.index)
87 *(.stab.indexstr)
88 *(.comment)
89 *(.note)
90 }
91 51
92 /* Sections to be discarded */ 52 /* Sections to be discarded */
93 DISCARDS 53 DISCARDS
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index ef70ca070ce2..4d3828959fb0 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -86,6 +86,20 @@ static inline int put_reg(struct task_struct *task, int regno,
86 return 0; 86 return 0;
87} 87}
88 88
89void user_enable_single_step(struct task_struct *task)
90{
91 unsigned long srflags;
92 srflags = get_reg(task, PT_SR) | (TRACE_BITS << 16);
93 put_reg(task, PT_SR, srflags);
94}
95
96void user_disable_single_step(struct task_struct *task)
97{
98 unsigned long srflags;
99 srflags = get_reg(task, PT_SR) & ~(TRACE_BITS << 16);
100 put_reg(task, PT_SR, srflags);
101}
102
89/* 103/*
90 * Called by kernel/ptrace.c when detaching.. 104 * Called by kernel/ptrace.c when detaching..
91 * 105 *
@@ -93,10 +107,8 @@ static inline int put_reg(struct task_struct *task, int regno,
93 */ 107 */
94void ptrace_disable(struct task_struct *child) 108void ptrace_disable(struct task_struct *child)
95{ 109{
96 unsigned long tmp;
97 /* make sure the single step bit is not set. */ 110 /* make sure the single step bit is not set. */
98 tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); 111 user_disable_single_step(child);
99 put_reg(child, PT_SR, tmp);
100} 112}
101 113
102long arch_ptrace(struct task_struct *child, long request, long addr, long data) 114long arch_ptrace(struct task_struct *child, long request, long addr, long data)
diff --git a/drivers/dio/dio-driver.c b/drivers/dio/dio-driver.c
index 9c0c9afcd0ac..a7b174ef4c85 100644
--- a/drivers/dio/dio-driver.c
+++ b/drivers/dio/dio-driver.c
@@ -140,5 +140,4 @@ postcore_initcall(dio_driver_init);
140EXPORT_SYMBOL(dio_match_device); 140EXPORT_SYMBOL(dio_match_device);
141EXPORT_SYMBOL(dio_register_driver); 141EXPORT_SYMBOL(dio_register_driver);
142EXPORT_SYMBOL(dio_unregister_driver); 142EXPORT_SYMBOL(dio_unregister_driver);
143EXPORT_SYMBOL(dio_dev_driver);
144EXPORT_SYMBOL(dio_bus_type); 143EXPORT_SYMBOL(dio_bus_type);
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
index 6dec9ba5ed28..362db31d8ca6 100644
--- a/drivers/parport/parport_mfc3.c
+++ b/drivers/parport/parport_mfc3.c
@@ -386,7 +386,7 @@ static void __exit parport_mfc3_exit(void)
386 if (!this_port[i]) 386 if (!this_port[i])
387 continue; 387 continue;
388 parport_remove_port(this_port[i]); 388 parport_remove_port(this_port[i]);
389 if (!this_port[i]->irq != PARPORT_IRQ_NONE) { 389 if (this_port[i]->irq != PARPORT_IRQ_NONE) {
390 if (--use_cnt == 0) 390 if (--use_cnt == 0)
391 free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops); 391 free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
392 } 392 }
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e11e1cda4ba2..f2e1004d12c7 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -509,6 +509,15 @@ config RTC_DRV_M48T59
509 This driver can also be built as a module, if so, the module 509 This driver can also be built as a module, if so, the module
510 will be called "rtc-m48t59". 510 will be called "rtc-m48t59".
511 511
512config RTC_DRV_MSM6242
513 tristate "Oki MSM6242"
514 help
515 If you say yes here you get support for the Oki MSM6242
516 timekeeping chip. It is used in some Amiga models (e.g. A2000).
517
518 This driver can also be built as a module. If so, the module
519 will be called rtc-msm6242.
520
512config RTC_MXC 521config RTC_MXC
513 tristate "Freescale MXC Real Time Clock" 522 tristate "Freescale MXC Real Time Clock"
514 depends on ARCH_MXC 523 depends on ARCH_MXC
@@ -529,6 +538,16 @@ config RTC_DRV_BQ4802
529 This driver can also be built as a module. If so, the module 538 This driver can also be built as a module. If so, the module
530 will be called rtc-bq4802. 539 will be called rtc-bq4802.
531 540
541config RTC_DRV_RP5C01
542 tristate "Ricoh RP5C01"
543 help
544 If you say yes here you get support for the Ricoh RP5C01
545 timekeeping chip. It is used in some Amiga models (e.g. A3000
546 and A4000).
547
548 This driver can also be built as a module. If so, the module
549 will be called rtc-rp5c01.
550
532config RTC_DRV_V3020 551config RTC_DRV_V3020
533 tristate "EM Microelectronic V3020" 552 tristate "EM Microelectronic V3020"
534 help 553 help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index aa3fbd5517a1..af1ba7ae2857 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
52obj-$(CONFIG_RTC_MXC) += rtc-mxc.o 52obj-$(CONFIG_RTC_MXC) += rtc-mxc.o
53obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o 53obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
54obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o 54obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
55obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
55obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o 56obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
56obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o 57obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
57obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o 58obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o
@@ -64,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
64obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o 65obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
65obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o 66obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
66obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o 67obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
68obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o
67obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o 69obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
68obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o 70obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
69obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o 71obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c
new file mode 100644
index 000000000000..5f5968a48925
--- /dev/null
+++ b/drivers/rtc/rtc-msm6242.c
@@ -0,0 +1,269 @@
1/*
2 * Oki MSM6242 RTC Driver
3 *
4 * Copyright 2009 Geert Uytterhoeven
5 *
6 * Based on the A2000 TOD code in arch/m68k/amiga/config.c
7 * Copyright (C) 1993 Hamish Macdonald
8 */
9
10#include <linux/delay.h>
11#include <linux/io.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/rtc.h>
16
17
18enum {
19 MSM6242_SECOND1 = 0x0, /* 1-second digit register */
20 MSM6242_SECOND10 = 0x1, /* 10-second digit register */
21 MSM6242_MINUTE1 = 0x2, /* 1-minute digit register */
22 MSM6242_MINUTE10 = 0x3, /* 10-minute digit register */
23 MSM6242_HOUR1 = 0x4, /* 1-hour digit register */
24 MSM6242_HOUR10 = 0x5, /* PM/AM, 10-hour digit register */
25 MSM6242_DAY1 = 0x6, /* 1-day digit register */
26 MSM6242_DAY10 = 0x7, /* 10-day digit register */
27 MSM6242_MONTH1 = 0x8, /* 1-month digit register */
28 MSM6242_MONTH10 = 0x9, /* 10-month digit register */
29 MSM6242_YEAR1 = 0xa, /* 1-year digit register */
30 MSM6242_YEAR10 = 0xb, /* 10-year digit register */
31 MSM6242_WEEK = 0xc, /* Week register */
32 MSM6242_CD = 0xd, /* Control Register D */
33 MSM6242_CE = 0xe, /* Control Register E */
34 MSM6242_CF = 0xf, /* Control Register F */
35};
36
37#define MSM6242_HOUR10_AM (0 << 2)
38#define MSM6242_HOUR10_PM (1 << 2)
39#define MSM6242_HOUR10_HR_MASK (3 << 0)
40
41#define MSM6242_WEEK_SUNDAY 0
42#define MSM6242_WEEK_MONDAY 1
43#define MSM6242_WEEK_TUESDAY 2
44#define MSM6242_WEEK_WEDNESDAY 3
45#define MSM6242_WEEK_THURSDAY 4
46#define MSM6242_WEEK_FRIDAY 5
47#define MSM6242_WEEK_SATURDAY 6
48
49#define MSM6242_CD_30_S_ADJ (1 << 3) /* 30-second adjustment */
50#define MSM6242_CD_IRQ_FLAG (1 << 2)
51#define MSM6242_CD_BUSY (1 << 1)
52#define MSM6242_CD_HOLD (1 << 0)
53
54#define MSM6242_CE_T_MASK (3 << 2)
55#define MSM6242_CE_T_64HZ (0 << 2) /* period 1/64 second */
56#define MSM6242_CE_T_1HZ (1 << 2) /* period 1 second */
57#define MSM6242_CE_T_1MINUTE (2 << 2) /* period 1 minute */
58#define MSM6242_CE_T_1HOUR (3 << 2) /* period 1 hour */
59
60#define MSM6242_CE_ITRPT_STND (1 << 1)
61#define MSM6242_CE_MASK (1 << 0) /* STD.P output control */
62
63#define MSM6242_CF_TEST (1 << 3)
64#define MSM6242_CF_12H (0 << 2)
65#define MSM6242_CF_24H (1 << 2)
66#define MSM6242_CF_STOP (1 << 1)
67#define MSM6242_CF_REST (1 << 0) /* reset */
68
69
70struct msm6242_priv {
71 u32 __iomem *regs;
72 struct rtc_device *rtc;
73};
74
75static inline unsigned int msm6242_read(struct msm6242_priv *priv,
76 unsigned int reg)
77{
78 return __raw_readl(&priv->regs[reg]) & 0xf;
79}
80
81static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val,
82 unsigned int reg)
83{
84 return __raw_writel(val, &priv->regs[reg]);
85}
86
87static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val,
88 unsigned int reg)
89{
90 msm6242_write(priv, msm6242_read(priv, reg) | val, reg);
91}
92
93static inline void msm6242_clear(struct msm6242_priv *priv, unsigned int val,
94 unsigned int reg)
95{
96 msm6242_write(priv, msm6242_read(priv, reg) & ~val, reg);
97}
98
99static void msm6242_lock(struct msm6242_priv *priv)
100{
101 int cnt = 5;
102
103 msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
104
105 while ((msm6242_read(priv, MSM6242_CD) & MSM6242_CD_BUSY) && cnt) {
106 msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
107 udelay(70);
108 msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
109 cnt--;
110 }
111
112 if (!cnt)
113 pr_warning("msm6242: timed out waiting for RTC (0x%x)\n",
114 msm6242_read(priv, MSM6242_CD));
115}
116
117static void msm6242_unlock(struct msm6242_priv *priv)
118{
119 msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
120}
121
122static int msm6242_read_time(struct device *dev, struct rtc_time *tm)
123{
124 struct msm6242_priv *priv = dev_get_drvdata(dev);
125
126 msm6242_lock(priv);
127
128 tm->tm_sec = msm6242_read(priv, MSM6242_SECOND10) * 10 +
129 msm6242_read(priv, MSM6242_SECOND1);
130 tm->tm_min = msm6242_read(priv, MSM6242_MINUTE10) * 10 +
131 msm6242_read(priv, MSM6242_MINUTE1);
132 tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10 & 3)) * 10 +
133 msm6242_read(priv, MSM6242_HOUR1);
134 tm->tm_mday = msm6242_read(priv, MSM6242_DAY10) * 10 +
135 msm6242_read(priv, MSM6242_DAY1);
136 tm->tm_wday = msm6242_read(priv, MSM6242_WEEK);
137 tm->tm_mon = msm6242_read(priv, MSM6242_MONTH10) * 10 +
138 msm6242_read(priv, MSM6242_MONTH1) - 1;
139 tm->tm_year = msm6242_read(priv, MSM6242_YEAR10) * 10 +
140 msm6242_read(priv, MSM6242_YEAR1);
141 if (tm->tm_year <= 69)
142 tm->tm_year += 100;
143
144 if (!(msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)) {
145 unsigned int pm = msm6242_read(priv, MSM6242_HOUR10) &
146 MSM6242_HOUR10_PM;
147 if (!pm && tm->tm_hour == 12)
148 tm->tm_hour = 0;
149 else if (pm && tm->tm_hour != 12)
150 tm->tm_hour += 12;
151 }
152
153 msm6242_unlock(priv);
154
155 return rtc_valid_tm(tm);
156}
157
158static int msm6242_set_time(struct device *dev, struct rtc_time *tm)
159{
160 struct msm6242_priv *priv = dev_get_drvdata(dev);
161
162 msm6242_lock(priv);
163
164 msm6242_write(priv, tm->tm_sec / 10, MSM6242_SECOND10);
165 msm6242_write(priv, tm->tm_sec % 10, MSM6242_SECOND1);
166 msm6242_write(priv, tm->tm_min / 10, MSM6242_MINUTE10);
167 msm6242_write(priv, tm->tm_min % 10, MSM6242_MINUTE1);
168 if (msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)
169 msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
170 else if (tm->tm_hour >= 12)
171 msm6242_write(priv, MSM6242_HOUR10_PM + (tm->tm_hour - 12) / 10,
172 MSM6242_HOUR10);
173 else
174 msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
175 msm6242_write(priv, tm->tm_hour % 10, MSM6242_HOUR1);
176 msm6242_write(priv, tm->tm_mday / 10, MSM6242_DAY10);
177 msm6242_write(priv, tm->tm_mday % 10, MSM6242_DAY1);
178 if (tm->tm_wday != -1)
179 msm6242_write(priv, tm->tm_wday, MSM6242_WEEK);
180 msm6242_write(priv, (tm->tm_mon + 1) / 10, MSM6242_MONTH10);
181 msm6242_write(priv, (tm->tm_mon + 1) % 10, MSM6242_MONTH1);
182 if (tm->tm_year >= 100)
183 tm->tm_year -= 100;
184 msm6242_write(priv, tm->tm_year / 10, MSM6242_YEAR10);
185 msm6242_write(priv, tm->tm_year % 10, MSM6242_YEAR1);
186
187 msm6242_unlock(priv);
188 return 0;
189}
190
191static const struct rtc_class_ops msm6242_rtc_ops = {
192 .read_time = msm6242_read_time,
193 .set_time = msm6242_set_time,
194};
195
196static int __init msm6242_rtc_probe(struct platform_device *dev)
197{
198 struct resource *res;
199 struct msm6242_priv *priv;
200 struct rtc_device *rtc;
201 int error;
202
203 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
204 if (!res)
205 return -ENODEV;
206
207 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
208 if (!priv)
209 return -ENOMEM;
210
211 priv->regs = ioremap(res->start, resource_size(res));
212 if (!priv->regs) {
213 error = -ENOMEM;
214 goto out_free_priv;
215 }
216
217 rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops,
218 THIS_MODULE);
219 if (IS_ERR(rtc)) {
220 error = PTR_ERR(rtc);
221 goto out_unmap;
222 }
223
224 priv->rtc = rtc;
225 platform_set_drvdata(dev, priv);
226 return 0;
227
228out_unmap:
229 iounmap(priv->regs);
230out_free_priv:
231 kfree(priv);
232 return error;
233}
234
235static int __exit msm6242_rtc_remove(struct platform_device *dev)
236{
237 struct msm6242_priv *priv = platform_get_drvdata(dev);
238
239 rtc_device_unregister(priv->rtc);
240 iounmap(priv->regs);
241 kfree(priv);
242 return 0;
243}
244
245static struct platform_driver msm6242_rtc_driver = {
246 .driver = {
247 .name = "rtc-msm6242",
248 .owner = THIS_MODULE,
249 },
250 .remove = __exit_p(msm6242_rtc_remove),
251};
252
253static int __init msm6242_rtc_init(void)
254{
255 return platform_driver_probe(&msm6242_rtc_driver, msm6242_rtc_probe);
256}
257
258static void __exit msm6242_rtc_fini(void)
259{
260 platform_driver_unregister(&msm6242_rtc_driver);
261}
262
263module_init(msm6242_rtc_init);
264module_exit(msm6242_rtc_fini);
265
266MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
267MODULE_LICENSE("GPL");
268MODULE_DESCRIPTION("Oki MSM6242 RTC driver");
269MODULE_ALIAS("platform:rtc-msm6242");
diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c
new file mode 100644
index 000000000000..e1313feb060f
--- /dev/null
+++ b/drivers/rtc/rtc-rp5c01.c
@@ -0,0 +1,222 @@
1/*
2 * Ricoh RP5C01 RTC Driver
3 *
4 * Copyright 2009 Geert Uytterhoeven
5 *
6 * Based on the A3000 TOD code in arch/m68k/amiga/config.c
7 * Copyright (C) 1993 Hamish Macdonald
8 */
9
10#include <linux/io.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/rtc.h>
15
16
17enum {
18 RP5C01_1_SECOND = 0x0, /* MODE 00 */
19 RP5C01_10_SECOND = 0x1, /* MODE 00 */
20 RP5C01_1_MINUTE = 0x2, /* MODE 00 and MODE 01 */
21 RP5C01_10_MINUTE = 0x3, /* MODE 00 and MODE 01 */
22 RP5C01_1_HOUR = 0x4, /* MODE 00 and MODE 01 */
23 RP5C01_10_HOUR = 0x5, /* MODE 00 and MODE 01 */
24 RP5C01_DAY_OF_WEEK = 0x6, /* MODE 00 and MODE 01 */
25 RP5C01_1_DAY = 0x7, /* MODE 00 and MODE 01 */
26 RP5C01_10_DAY = 0x8, /* MODE 00 and MODE 01 */
27 RP5C01_1_MONTH = 0x9, /* MODE 00 */
28 RP5C01_10_MONTH = 0xa, /* MODE 00 */
29 RP5C01_1_YEAR = 0xb, /* MODE 00 */
30 RP5C01_10_YEAR = 0xc, /* MODE 00 */
31
32 RP5C01_12_24_SELECT = 0xa, /* MODE 01 */
33 RP5C01_LEAP_YEAR = 0xb, /* MODE 01 */
34
35 RP5C01_MODE = 0xd, /* all modes */
36 RP5C01_TEST = 0xe, /* all modes */
37 RP5C01_RESET = 0xf, /* all modes */
38};
39
40#define RP5C01_12_24_SELECT_12 (0 << 0)
41#define RP5C01_12_24_SELECT_24 (1 << 0)
42
43#define RP5C01_10_HOUR_AM (0 << 1)
44#define RP5C01_10_HOUR_PM (1 << 1)
45
46#define RP5C01_MODE_TIMER_EN (1 << 3) /* timer enable */
47#define RP5C01_MODE_ALARM_EN (1 << 2) /* alarm enable */
48
49#define RP5C01_MODE_MODE_MASK (3 << 0)
50#define RP5C01_MODE_MODE00 (0 << 0) /* time */
51#define RP5C01_MODE_MODE01 (1 << 0) /* alarm, 12h/24h, leap year */
52#define RP5C01_MODE_RAM_BLOCK10 (2 << 0) /* RAM 4 bits x 13 */
53#define RP5C01_MODE_RAM_BLOCK11 (3 << 0) /* RAM 4 bits x 13 */
54
55#define RP5C01_RESET_1HZ_PULSE (1 << 3)
56#define RP5C01_RESET_16HZ_PULSE (1 << 2)
57#define RP5C01_RESET_SECOND (1 << 1) /* reset divider stages for */
58 /* seconds or smaller units */
59#define RP5C01_RESET_ALARM (1 << 0) /* reset all alarm registers */
60
61
62struct rp5c01_priv {
63 u32 __iomem *regs;
64 struct rtc_device *rtc;
65};
66
67static inline unsigned int rp5c01_read(struct rp5c01_priv *priv,
68 unsigned int reg)
69{
70 return __raw_readl(&priv->regs[reg]) & 0xf;
71}
72
73static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val,
74 unsigned int reg)
75{
76 return __raw_writel(val, &priv->regs[reg]);
77}
78
79static void rp5c01_lock(struct rp5c01_priv *priv)
80{
81 rp5c01_write(priv, RP5C01_MODE_MODE00, RP5C01_MODE);
82}
83
84static void rp5c01_unlock(struct rp5c01_priv *priv)
85{
86 rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_MODE01,
87 RP5C01_MODE);
88}
89
90static int rp5c01_read_time(struct device *dev, struct rtc_time *tm)
91{
92 struct rp5c01_priv *priv = dev_get_drvdata(dev);
93
94 rp5c01_lock(priv);
95
96 tm->tm_sec = rp5c01_read(priv, RP5C01_10_SECOND) * 10 +
97 rp5c01_read(priv, RP5C01_1_SECOND);
98 tm->tm_min = rp5c01_read(priv, RP5C01_10_MINUTE) * 10 +
99 rp5c01_read(priv, RP5C01_1_MINUTE);
100 tm->tm_hour = rp5c01_read(priv, RP5C01_10_HOUR) * 10 +
101 rp5c01_read(priv, RP5C01_1_HOUR);
102 tm->tm_mday = rp5c01_read(priv, RP5C01_10_DAY) * 10 +
103 rp5c01_read(priv, RP5C01_1_DAY);
104 tm->tm_wday = rp5c01_read(priv, RP5C01_DAY_OF_WEEK);
105 tm->tm_mon = rp5c01_read(priv, RP5C01_10_MONTH) * 10 +
106 rp5c01_read(priv, RP5C01_1_MONTH) - 1;
107 tm->tm_year = rp5c01_read(priv, RP5C01_10_YEAR) * 10 +
108 rp5c01_read(priv, RP5C01_1_YEAR);
109 if (tm->tm_year <= 69)
110 tm->tm_year += 100;
111
112 rp5c01_unlock(priv);
113
114 return rtc_valid_tm(tm);
115}
116
117static int rp5c01_set_time(struct device *dev, struct rtc_time *tm)
118{
119 struct rp5c01_priv *priv = dev_get_drvdata(dev);
120
121 rp5c01_lock(priv);
122
123 rp5c01_write(priv, tm->tm_sec / 10, RP5C01_10_SECOND);
124 rp5c01_write(priv, tm->tm_sec % 10, RP5C01_1_SECOND);
125 rp5c01_write(priv, tm->tm_min / 10, RP5C01_10_MINUTE);
126 rp5c01_write(priv, tm->tm_min % 10, RP5C01_1_MINUTE);
127 rp5c01_write(priv, tm->tm_hour / 10, RP5C01_10_HOUR);
128 rp5c01_write(priv, tm->tm_hour % 10, RP5C01_1_HOUR);
129 rp5c01_write(priv, tm->tm_mday / 10, RP5C01_10_DAY);
130 rp5c01_write(priv, tm->tm_mday % 10, RP5C01_1_DAY);
131 if (tm->tm_wday != -1)
132 rp5c01_write(priv, tm->tm_wday, RP5C01_DAY_OF_WEEK);
133 rp5c01_write(priv, (tm->tm_mon + 1) / 10, RP5C01_10_MONTH);
134 rp5c01_write(priv, (tm->tm_mon + 1) % 10, RP5C01_1_MONTH);
135 if (tm->tm_year >= 100)
136 tm->tm_year -= 100;
137 rp5c01_write(priv, tm->tm_year / 10, RP5C01_10_YEAR);
138 rp5c01_write(priv, tm->tm_year % 10, RP5C01_1_YEAR);
139
140 rp5c01_unlock(priv);
141 return 0;
142}
143
144static const struct rtc_class_ops rp5c01_rtc_ops = {
145 .read_time = rp5c01_read_time,
146 .set_time = rp5c01_set_time,
147};
148
149static int __init rp5c01_rtc_probe(struct platform_device *dev)
150{
151 struct resource *res;
152 struct rp5c01_priv *priv;
153 struct rtc_device *rtc;
154 int error;
155
156 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
157 if (!res)
158 return -ENODEV;
159
160 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
161 if (!priv)
162 return -ENOMEM;
163
164 priv->regs = ioremap(res->start, resource_size(res));
165 if (!priv->regs) {
166 error = -ENOMEM;
167 goto out_free_priv;
168 }
169
170 rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops,
171 THIS_MODULE);
172 if (IS_ERR(rtc)) {
173 error = PTR_ERR(rtc);
174 goto out_unmap;
175 }
176
177 priv->rtc = rtc;
178 platform_set_drvdata(dev, priv);
179 return 0;
180
181out_unmap:
182 iounmap(priv->regs);
183out_free_priv:
184 kfree(priv);
185 return error;
186}
187
188static int __exit rp5c01_rtc_remove(struct platform_device *dev)
189{
190 struct rp5c01_priv *priv = platform_get_drvdata(dev);
191
192 rtc_device_unregister(priv->rtc);
193 iounmap(priv->regs);
194 kfree(priv);
195 return 0;
196}
197
198static struct platform_driver rp5c01_rtc_driver = {
199 .driver = {
200 .name = "rtc-rp5c01",
201 .owner = THIS_MODULE,
202 },
203 .remove = __exit_p(rp5c01_rtc_remove),
204};
205
206static int __init rp5c01_rtc_init(void)
207{
208 return platform_driver_probe(&rp5c01_rtc_driver, rp5c01_rtc_probe);
209}
210
211static void __exit rp5c01_rtc_fini(void)
212{
213 platform_driver_unregister(&rp5c01_rtc_driver);
214}
215
216module_init(rp5c01_rtc_init);
217module_exit(rp5c01_rtc_fini);
218
219MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
220MODULE_LICENSE("GPL");
221MODULE_DESCRIPTION("Ricoh RP5C01 RTC driver");
222MODULE_ALIAS("platform:rtc-rp5c01");
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 37624f74e88b..b7687c55fe16 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2242,6 +2242,9 @@ static int ext_setcolreg(unsigned int regno, unsigned int red,
2242 if (!external_vgaiobase) 2242 if (!external_vgaiobase)
2243 return 1; 2243 return 1;
2244 2244
2245 if (regno > 255)
2246 return 1;
2247
2245 switch (external_card_type) { 2248 switch (external_card_type) {
2246 case IS_VGA: 2249 case IS_VGA:
2247 OUTB(0x3c8, regno); 2250 OUTB(0x3c8, regno);
diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c
index e6c4390d8bd6..53180a37cc9a 100644
--- a/drivers/zorro/zorro-driver.c
+++ b/drivers/zorro/zorro-driver.c
@@ -156,5 +156,4 @@ postcore_initcall(zorro_driver_init);
156EXPORT_SYMBOL(zorro_match_device); 156EXPORT_SYMBOL(zorro_match_device);
157EXPORT_SYMBOL(zorro_register_driver); 157EXPORT_SYMBOL(zorro_register_driver);
158EXPORT_SYMBOL(zorro_unregister_driver); 158EXPORT_SYMBOL(zorro_unregister_driver);
159EXPORT_SYMBOL(zorro_dev_driver);
160EXPORT_SYMBOL(zorro_bus_type); 159EXPORT_SYMBOL(zorro_bus_type);