diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-18 09:27:55 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-12-18 09:27:55 -0500 |
commit | 2f841ed13b9f10037e25ddf417d01700ecd886d0 (patch) | |
tree | 123448d98b3be03ac90fbb6e32f224235063c8bf /arch/arm | |
parent | 961ec6daa7b14f376c30d447a830fa4783a2112c (diff) | |
parent | 8fbf397c3389c1dedfa9ee412715046ab28fd82d (diff) |
Merge branch 'hw-breakpoint' of git://repo.or.cz/linux-2.6/linux-wd into devel-stable
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/hw_breakpoint.h | 4 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 4 | ||||
-rw-r--r-- | arch/arm/kernel/entry-header.S | 19 | ||||
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 543 | ||||
-rw-r--r-- | arch/arm/kernel/ptrace.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm24xx.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/serial.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/h1940-bluetooth.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-s3c2416/irq.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-s3c2443/irq.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-s3c64xx/mach-mini6410.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c64xx/mach-real6410.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/mach-smdkc110.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-s5pv210/mach-smdkv210.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 147 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 33 | ||||
-rw-r--r-- | arch/arm/plat-pxa/include/plat/sdhci.h | 3 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c | 6 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c | 6 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c | 6 |
21 files changed, 512 insertions, 311 deletions
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index 4d8ae9d67ab..f389b2704d8 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h | |||
@@ -20,8 +20,8 @@ struct arch_hw_breakpoint_ctrl { | |||
20 | struct arch_hw_breakpoint { | 20 | struct arch_hw_breakpoint { |
21 | u32 address; | 21 | u32 address; |
22 | u32 trigger; | 22 | u32 trigger; |
23 | struct perf_event *suspended_wp; | 23 | struct arch_hw_breakpoint_ctrl step_ctrl; |
24 | struct arch_hw_breakpoint_ctrl ctrl; | 24 | struct arch_hw_breakpoint_ctrl ctrl; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) | 27 | static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index c09e3573c5d..34bbef0d2e7 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -198,6 +198,7 @@ __dabt_svc: | |||
198 | @ | 198 | @ |
199 | @ set desired IRQ state, then call main handler | 199 | @ set desired IRQ state, then call main handler |
200 | @ | 200 | @ |
201 | debug_entry r1 | ||
201 | msr cpsr_c, r9 | 202 | msr cpsr_c, r9 |
202 | mov r2, sp | 203 | mov r2, sp |
203 | bl do_DataAbort | 204 | bl do_DataAbort |
@@ -324,6 +325,7 @@ __pabt_svc: | |||
324 | #else | 325 | #else |
325 | bl CPU_PABORT_HANDLER | 326 | bl CPU_PABORT_HANDLER |
326 | #endif | 327 | #endif |
328 | debug_entry r1 | ||
327 | msr cpsr_c, r9 @ Maybe enable interrupts | 329 | msr cpsr_c, r9 @ Maybe enable interrupts |
328 | mov r2, sp @ regs | 330 | mov r2, sp @ regs |
329 | bl do_PrefetchAbort @ call abort handler | 331 | bl do_PrefetchAbort @ call abort handler |
@@ -439,6 +441,7 @@ __dabt_usr: | |||
439 | @ | 441 | @ |
440 | @ IRQs on, then call the main handler | 442 | @ IRQs on, then call the main handler |
441 | @ | 443 | @ |
444 | debug_entry r1 | ||
442 | enable_irq | 445 | enable_irq |
443 | mov r2, sp | 446 | mov r2, sp |
444 | adr lr, BSYM(ret_from_exception) | 447 | adr lr, BSYM(ret_from_exception) |
@@ -703,6 +706,7 @@ __pabt_usr: | |||
703 | #else | 706 | #else |
704 | bl CPU_PABORT_HANDLER | 707 | bl CPU_PABORT_HANDLER |
705 | #endif | 708 | #endif |
709 | debug_entry r1 | ||
706 | enable_irq @ Enable interrupts | 710 | enable_irq @ Enable interrupts |
707 | mov r2, sp @ regs | 711 | mov r2, sp @ regs |
708 | bl do_PrefetchAbort @ call abort handler | 712 | bl do_PrefetchAbort @ call abort handler |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index d93f976fb38..ae946490016 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
@@ -165,6 +165,25 @@ | |||
165 | .endm | 165 | .endm |
166 | #endif /* !CONFIG_THUMB2_KERNEL */ | 166 | #endif /* !CONFIG_THUMB2_KERNEL */ |
167 | 167 | ||
168 | @ | ||
169 | @ Debug exceptions are taken as prefetch or data aborts. | ||
170 | @ We must disable preemption during the handler so that | ||
171 | @ we can access the debug registers safely. | ||
172 | @ | ||
173 | .macro debug_entry, fsr | ||
174 | #if defined(CONFIG_HAVE_HW_BREAKPOINT) && defined(CONFIG_PREEMPT) | ||
175 | ldr r4, =0x40f @ mask out fsr.fs | ||
176 | and r5, r4, \fsr | ||
177 | cmp r5, #2 @ debug exception | ||
178 | bne 1f | ||
179 | get_thread_info r10 | ||
180 | ldr r6, [r10, #TI_PREEMPT] @ get preempt count | ||
181 | add r11, r6, #1 @ increment it | ||
182 | str r11, [r10, #TI_PREEMPT] | ||
183 | 1: | ||
184 | #endif | ||
185 | .endm | ||
186 | |||
168 | /* | 187 | /* |
169 | * These are the registers used in the syscall handler, and allow us to | 188 | * These are the registers used in the syscall handler, and allow us to |
170 | * have in theory up to 7 arguments to a function - r0 to r6. | 189 | * have in theory up to 7 arguments to a function - r0 to r6. |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 21e3a4ab3b8..c9f3f046757 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #define pr_fmt(fmt) "hw-breakpoint: " fmt | 24 | #define pr_fmt(fmt) "hw-breakpoint: " fmt |
25 | 25 | ||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/hardirq.h> | ||
27 | #include <linux/perf_event.h> | 28 | #include <linux/perf_event.h> |
28 | #include <linux/hw_breakpoint.h> | 29 | #include <linux/hw_breakpoint.h> |
29 | #include <linux/smp.h> | 30 | #include <linux/smp.h> |
@@ -44,6 +45,7 @@ static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]); | |||
44 | 45 | ||
45 | /* Number of BRP/WRP registers on this CPU. */ | 46 | /* Number of BRP/WRP registers on this CPU. */ |
46 | static int core_num_brps; | 47 | static int core_num_brps; |
48 | static int core_num_reserved_brps; | ||
47 | static int core_num_wrps; | 49 | static int core_num_wrps; |
48 | 50 | ||
49 | /* Debug architecture version. */ | 51 | /* Debug architecture version. */ |
@@ -52,87 +54,6 @@ static u8 debug_arch; | |||
52 | /* Maximum supported watchpoint length. */ | 54 | /* Maximum supported watchpoint length. */ |
53 | static u8 max_watchpoint_len; | 55 | static u8 max_watchpoint_len; |
54 | 56 | ||
55 | /* Determine number of BRP registers available. */ | ||
56 | static int get_num_brps(void) | ||
57 | { | ||
58 | u32 didr; | ||
59 | ARM_DBG_READ(c0, 0, didr); | ||
60 | return ((didr >> 24) & 0xf) + 1; | ||
61 | } | ||
62 | |||
63 | /* Determine number of WRP registers available. */ | ||
64 | static int get_num_wrps(void) | ||
65 | { | ||
66 | /* | ||
67 | * FIXME: When a watchpoint fires, the only way to work out which | ||
68 | * watchpoint it was is by disassembling the faulting instruction | ||
69 | * and working out the address of the memory access. | ||
70 | * | ||
71 | * Furthermore, we can only do this if the watchpoint was precise | ||
72 | * since imprecise watchpoints prevent us from calculating register | ||
73 | * based addresses. | ||
74 | * | ||
75 | * For the time being, we only report 1 watchpoint register so we | ||
76 | * always know which watchpoint fired. In the future we can either | ||
77 | * add a disassembler and address generation emulator, or we can | ||
78 | * insert a check to see if the DFAR is set on watchpoint exception | ||
79 | * entry [the ARM ARM states that the DFAR is UNKNOWN, but | ||
80 | * experience shows that it is set on some implementations]. | ||
81 | */ | ||
82 | |||
83 | #if 0 | ||
84 | u32 didr, wrps; | ||
85 | ARM_DBG_READ(c0, 0, didr); | ||
86 | return ((didr >> 28) & 0xf) + 1; | ||
87 | #endif | ||
88 | |||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | int hw_breakpoint_slots(int type) | ||
93 | { | ||
94 | /* | ||
95 | * We can be called early, so don't rely on | ||
96 | * our static variables being initialised. | ||
97 | */ | ||
98 | switch (type) { | ||
99 | case TYPE_INST: | ||
100 | return get_num_brps(); | ||
101 | case TYPE_DATA: | ||
102 | return get_num_wrps(); | ||
103 | default: | ||
104 | pr_warning("unknown slot type: %d\n", type); | ||
105 | return 0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* Determine debug architecture. */ | ||
110 | static u8 get_debug_arch(void) | ||
111 | { | ||
112 | u32 didr; | ||
113 | |||
114 | /* Do we implement the extended CPUID interface? */ | ||
115 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | ||
116 | pr_warning("CPUID feature registers not supported. " | ||
117 | "Assuming v6 debug is present.\n"); | ||
118 | return ARM_DEBUG_ARCH_V6; | ||
119 | } | ||
120 | |||
121 | ARM_DBG_READ(c0, 0, didr); | ||
122 | return (didr >> 16) & 0xf; | ||
123 | } | ||
124 | |||
125 | /* Does this core support mismatch breakpoints? */ | ||
126 | static int core_has_mismatch_bps(void) | ||
127 | { | ||
128 | return debug_arch >= ARM_DEBUG_ARCH_V7_ECP14 && core_num_brps > 1; | ||
129 | } | ||
130 | |||
131 | u8 arch_get_debug_arch(void) | ||
132 | { | ||
133 | return debug_arch; | ||
134 | } | ||
135 | |||
136 | #define READ_WB_REG_CASE(OP2, M, VAL) \ | 57 | #define READ_WB_REG_CASE(OP2, M, VAL) \ |
137 | case ((OP2 << 4) + M): \ | 58 | case ((OP2 << 4) + M): \ |
138 | ARM_DBG_READ(c ## M, OP2, VAL); \ | 59 | ARM_DBG_READ(c ## M, OP2, VAL); \ |
@@ -210,6 +131,94 @@ static void write_wb_reg(int n, u32 val) | |||
210 | isb(); | 131 | isb(); |
211 | } | 132 | } |
212 | 133 | ||
134 | /* Determine debug architecture. */ | ||
135 | static u8 get_debug_arch(void) | ||
136 | { | ||
137 | u32 didr; | ||
138 | |||
139 | /* Do we implement the extended CPUID interface? */ | ||
140 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | ||
141 | pr_warning("CPUID feature registers not supported. " | ||
142 | "Assuming v6 debug is present.\n"); | ||
143 | return ARM_DEBUG_ARCH_V6; | ||
144 | } | ||
145 | |||
146 | ARM_DBG_READ(c0, 0, didr); | ||
147 | return (didr >> 16) & 0xf; | ||
148 | } | ||
149 | |||
150 | u8 arch_get_debug_arch(void) | ||
151 | { | ||
152 | return debug_arch; | ||
153 | } | ||
154 | |||
155 | /* Determine number of BRP register available. */ | ||
156 | static int get_num_brp_resources(void) | ||
157 | { | ||
158 | u32 didr; | ||
159 | ARM_DBG_READ(c0, 0, didr); | ||
160 | return ((didr >> 24) & 0xf) + 1; | ||
161 | } | ||
162 | |||
163 | /* Does this core support mismatch breakpoints? */ | ||
164 | static int core_has_mismatch_brps(void) | ||
165 | { | ||
166 | return (get_debug_arch() >= ARM_DEBUG_ARCH_V7_ECP14 && | ||
167 | get_num_brp_resources() > 1); | ||
168 | } | ||
169 | |||
170 | /* Determine number of usable WRPs available. */ | ||
171 | static int get_num_wrps(void) | ||
172 | { | ||
173 | /* | ||
174 | * FIXME: When a watchpoint fires, the only way to work out which | ||
175 | * watchpoint it was is by disassembling the faulting instruction | ||
176 | * and working out the address of the memory access. | ||
177 | * | ||
178 | * Furthermore, we can only do this if the watchpoint was precise | ||
179 | * since imprecise watchpoints prevent us from calculating register | ||
180 | * based addresses. | ||
181 | * | ||
182 | * Providing we have more than 1 breakpoint register, we only report | ||
183 | * a single watchpoint register for the time being. This way, we always | ||
184 | * know which watchpoint fired. In the future we can either add a | ||
185 | * disassembler and address generation emulator, or we can insert a | ||
186 | * check to see if the DFAR is set on watchpoint exception entry | ||
187 | * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows | ||
188 | * that it is set on some implementations]. | ||
189 | */ | ||
190 | |||
191 | #if 0 | ||
192 | int wrps; | ||
193 | u32 didr; | ||
194 | ARM_DBG_READ(c0, 0, didr); | ||
195 | wrps = ((didr >> 28) & 0xf) + 1; | ||
196 | #endif | ||
197 | int wrps = 1; | ||
198 | |||
199 | if (core_has_mismatch_brps() && wrps >= get_num_brp_resources()) | ||
200 | wrps = get_num_brp_resources() - 1; | ||
201 | |||
202 | return wrps; | ||
203 | } | ||
204 | |||
205 | /* We reserve one breakpoint for each watchpoint. */ | ||
206 | static int get_num_reserved_brps(void) | ||
207 | { | ||
208 | if (core_has_mismatch_brps()) | ||
209 | return get_num_wrps(); | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /* Determine number of usable BRPs available. */ | ||
214 | static int get_num_brps(void) | ||
215 | { | ||
216 | int brps = get_num_brp_resources(); | ||
217 | if (core_has_mismatch_brps()) | ||
218 | brps -= get_num_reserved_brps(); | ||
219 | return brps; | ||
220 | } | ||
221 | |||
213 | /* | 222 | /* |
214 | * In order to access the breakpoint/watchpoint control registers, | 223 | * In order to access the breakpoint/watchpoint control registers, |
215 | * we must be running in debug monitor mode. Unfortunately, we can | 224 | * we must be running in debug monitor mode. Unfortunately, we can |
@@ -230,8 +239,12 @@ static int enable_monitor_mode(void) | |||
230 | goto out; | 239 | goto out; |
231 | } | 240 | } |
232 | 241 | ||
242 | /* If monitor mode is already enabled, just return. */ | ||
243 | if (dscr & ARM_DSCR_MDBGEN) | ||
244 | goto out; | ||
245 | |||
233 | /* Write to the corresponding DSCR. */ | 246 | /* Write to the corresponding DSCR. */ |
234 | switch (debug_arch) { | 247 | switch (get_debug_arch()) { |
235 | case ARM_DEBUG_ARCH_V6: | 248 | case ARM_DEBUG_ARCH_V6: |
236 | case ARM_DEBUG_ARCH_V6_1: | 249 | case ARM_DEBUG_ARCH_V6_1: |
237 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); | 250 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); |
@@ -246,15 +259,30 @@ static int enable_monitor_mode(void) | |||
246 | 259 | ||
247 | /* Check that the write made it through. */ | 260 | /* Check that the write made it through. */ |
248 | ARM_DBG_READ(c1, 0, dscr); | 261 | ARM_DBG_READ(c1, 0, dscr); |
249 | if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN), | 262 | if (!(dscr & ARM_DSCR_MDBGEN)) |
250 | "failed to enable monitor mode.")) { | ||
251 | ret = -EPERM; | 263 | ret = -EPERM; |
252 | } | ||
253 | 264 | ||
254 | out: | 265 | out: |
255 | return ret; | 266 | return ret; |
256 | } | 267 | } |
257 | 268 | ||
269 | int hw_breakpoint_slots(int type) | ||
270 | { | ||
271 | /* | ||
272 | * We can be called early, so don't rely on | ||
273 | * our static variables being initialised. | ||
274 | */ | ||
275 | switch (type) { | ||
276 | case TYPE_INST: | ||
277 | return get_num_brps(); | ||
278 | case TYPE_DATA: | ||
279 | return get_num_wrps(); | ||
280 | default: | ||
281 | pr_warning("unknown slot type: %d\n", type); | ||
282 | return 0; | ||
283 | } | ||
284 | } | ||
285 | |||
258 | /* | 286 | /* |
259 | * Check if 8-bit byte-address select is available. | 287 | * Check if 8-bit byte-address select is available. |
260 | * This clobbers WRP 0. | 288 | * This clobbers WRP 0. |
@@ -268,9 +296,6 @@ static u8 get_max_wp_len(void) | |||
268 | if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14) | 296 | if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14) |
269 | goto out; | 297 | goto out; |
270 | 298 | ||
271 | if (enable_monitor_mode()) | ||
272 | goto out; | ||
273 | |||
274 | memset(&ctrl, 0, sizeof(ctrl)); | 299 | memset(&ctrl, 0, sizeof(ctrl)); |
275 | ctrl.len = ARM_BREAKPOINT_LEN_8; | 300 | ctrl.len = ARM_BREAKPOINT_LEN_8; |
276 | ctrl_reg = encode_ctrl_reg(ctrl); | 301 | ctrl_reg = encode_ctrl_reg(ctrl); |
@@ -290,23 +315,6 @@ u8 arch_get_max_wp_len(void) | |||
290 | } | 315 | } |
291 | 316 | ||
292 | /* | 317 | /* |
293 | * Handler for reactivating a suspended watchpoint when the single | ||
294 | * step `mismatch' breakpoint is triggered. | ||
295 | */ | ||
296 | static void wp_single_step_handler(struct perf_event *bp, int unused, | ||
297 | struct perf_sample_data *data, | ||
298 | struct pt_regs *regs) | ||
299 | { | ||
300 | perf_event_enable(counter_arch_bp(bp)->suspended_wp); | ||
301 | unregister_hw_breakpoint(bp); | ||
302 | } | ||
303 | |||
304 | static int bp_is_single_step(struct perf_event *bp) | ||
305 | { | ||
306 | return bp->overflow_handler == wp_single_step_handler; | ||
307 | } | ||
308 | |||
309 | /* | ||
310 | * Install a perf counter breakpoint. | 318 | * Install a perf counter breakpoint. |
311 | */ | 319 | */ |
312 | int arch_install_hw_breakpoint(struct perf_event *bp) | 320 | int arch_install_hw_breakpoint(struct perf_event *bp) |
@@ -314,30 +322,41 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
314 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 322 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
315 | struct perf_event **slot, **slots; | 323 | struct perf_event **slot, **slots; |
316 | int i, max_slots, ctrl_base, val_base, ret = 0; | 324 | int i, max_slots, ctrl_base, val_base, ret = 0; |
325 | u32 addr, ctrl; | ||
317 | 326 | ||
318 | /* Ensure that we are in monitor mode and halting mode is disabled. */ | 327 | /* Ensure that we are in monitor mode and halting mode is disabled. */ |
319 | ret = enable_monitor_mode(); | 328 | ret = enable_monitor_mode(); |
320 | if (ret) | 329 | if (ret) |
321 | goto out; | 330 | goto out; |
322 | 331 | ||
332 | addr = info->address; | ||
333 | ctrl = encode_ctrl_reg(info->ctrl) | 0x1; | ||
334 | |||
323 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { | 335 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { |
324 | /* Breakpoint */ | 336 | /* Breakpoint */ |
325 | ctrl_base = ARM_BASE_BCR; | 337 | ctrl_base = ARM_BASE_BCR; |
326 | val_base = ARM_BASE_BVR; | 338 | val_base = ARM_BASE_BVR; |
327 | slots = __get_cpu_var(bp_on_reg); | 339 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); |
328 | max_slots = core_num_brps - 1; | 340 | max_slots = core_num_brps; |
329 | 341 | if (info->step_ctrl.enabled) { | |
330 | if (bp_is_single_step(bp)) { | 342 | /* Override the breakpoint data with the step data. */ |
331 | info->ctrl.mismatch = 1; | 343 | addr = info->trigger & ~0x3; |
332 | i = max_slots; | 344 | ctrl = encode_ctrl_reg(info->step_ctrl); |
333 | slots[i] = bp; | ||
334 | goto setup; | ||
335 | } | 345 | } |
336 | } else { | 346 | } else { |
337 | /* Watchpoint */ | 347 | /* Watchpoint */ |
338 | ctrl_base = ARM_BASE_WCR; | 348 | if (info->step_ctrl.enabled) { |
339 | val_base = ARM_BASE_WVR; | 349 | /* Install into the reserved breakpoint region. */ |
340 | slots = __get_cpu_var(wp_on_reg); | 350 | ctrl_base = ARM_BASE_BCR + core_num_brps; |
351 | val_base = ARM_BASE_BVR + core_num_brps; | ||
352 | /* Override the watchpoint data with the step data. */ | ||
353 | addr = info->trigger & ~0x3; | ||
354 | ctrl = encode_ctrl_reg(info->step_ctrl); | ||
355 | } else { | ||
356 | ctrl_base = ARM_BASE_WCR; | ||
357 | val_base = ARM_BASE_WVR; | ||
358 | } | ||
359 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
341 | max_slots = core_num_wrps; | 360 | max_slots = core_num_wrps; |
342 | } | 361 | } |
343 | 362 | ||
@@ -355,12 +374,11 @@ int arch_install_hw_breakpoint(struct perf_event *bp) | |||
355 | goto out; | 374 | goto out; |
356 | } | 375 | } |
357 | 376 | ||
358 | setup: | ||
359 | /* Setup the address register. */ | 377 | /* Setup the address register. */ |
360 | write_wb_reg(val_base + i, info->address); | 378 | write_wb_reg(val_base + i, addr); |
361 | 379 | ||
362 | /* Setup the control register. */ | 380 | /* Setup the control register. */ |
363 | write_wb_reg(ctrl_base + i, encode_ctrl_reg(info->ctrl) | 0x1); | 381 | write_wb_reg(ctrl_base + i, ctrl); |
364 | 382 | ||
365 | out: | 383 | out: |
366 | return ret; | 384 | return ret; |
@@ -375,18 +393,15 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
375 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { | 393 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { |
376 | /* Breakpoint */ | 394 | /* Breakpoint */ |
377 | base = ARM_BASE_BCR; | 395 | base = ARM_BASE_BCR; |
378 | slots = __get_cpu_var(bp_on_reg); | 396 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); |
379 | max_slots = core_num_brps - 1; | 397 | max_slots = core_num_brps; |
380 | |||
381 | if (bp_is_single_step(bp)) { | ||
382 | i = max_slots; | ||
383 | slots[i] = NULL; | ||
384 | goto reset; | ||
385 | } | ||
386 | } else { | 398 | } else { |
387 | /* Watchpoint */ | 399 | /* Watchpoint */ |
388 | base = ARM_BASE_WCR; | 400 | if (info->step_ctrl.enabled) |
389 | slots = __get_cpu_var(wp_on_reg); | 401 | base = ARM_BASE_BCR + core_num_brps; |
402 | else | ||
403 | base = ARM_BASE_WCR; | ||
404 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
390 | max_slots = core_num_wrps; | 405 | max_slots = core_num_wrps; |
391 | } | 406 | } |
392 | 407 | ||
@@ -403,7 +418,6 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) | |||
403 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) | 418 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) |
404 | return; | 419 | return; |
405 | 420 | ||
406 | reset: | ||
407 | /* Reset the control register. */ | 421 | /* Reset the control register. */ |
408 | write_wb_reg(base + i, 0); | 422 | write_wb_reg(base + i, 0); |
409 | } | 423 | } |
@@ -537,12 +551,23 @@ static int arch_build_bp_info(struct perf_event *bp) | |||
537 | return -EINVAL; | 551 | return -EINVAL; |
538 | } | 552 | } |
539 | 553 | ||
554 | /* | ||
555 | * Breakpoints must be of length 2 (thumb) or 4 (ARM) bytes. | ||
556 | * Watchpoints can be of length 1, 2, 4 or 8 bytes if supported | ||
557 | * by the hardware and must be aligned to the appropriate number of | ||
558 | * bytes. | ||
559 | */ | ||
560 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE && | ||
561 | info->ctrl.len != ARM_BREAKPOINT_LEN_2 && | ||
562 | info->ctrl.len != ARM_BREAKPOINT_LEN_4) | ||
563 | return -EINVAL; | ||
564 | |||
540 | /* Address */ | 565 | /* Address */ |
541 | info->address = bp->attr.bp_addr; | 566 | info->address = bp->attr.bp_addr; |
542 | 567 | ||
543 | /* Privilege */ | 568 | /* Privilege */ |
544 | info->ctrl.privilege = ARM_BREAKPOINT_USER; | 569 | info->ctrl.privilege = ARM_BREAKPOINT_USER; |
545 | if (arch_check_bp_in_kernelspace(bp) && !bp_is_single_step(bp)) | 570 | if (arch_check_bp_in_kernelspace(bp)) |
546 | info->ctrl.privilege |= ARM_BREAKPOINT_PRIV; | 571 | info->ctrl.privilege |= ARM_BREAKPOINT_PRIV; |
547 | 572 | ||
548 | /* Enabled? */ | 573 | /* Enabled? */ |
@@ -561,7 +586,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
561 | { | 586 | { |
562 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 587 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
563 | int ret = 0; | 588 | int ret = 0; |
564 | u32 bytelen, max_len, offset, alignment_mask = 0x3; | 589 | u32 offset, alignment_mask = 0x3; |
565 | 590 | ||
566 | /* Build the arch_hw_breakpoint. */ | 591 | /* Build the arch_hw_breakpoint. */ |
567 | ret = arch_build_bp_info(bp); | 592 | ret = arch_build_bp_info(bp); |
@@ -571,84 +596,85 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
571 | /* Check address alignment. */ | 596 | /* Check address alignment. */ |
572 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) | 597 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) |
573 | alignment_mask = 0x7; | 598 | alignment_mask = 0x7; |
574 | if (info->address & alignment_mask) { | 599 | offset = info->address & alignment_mask; |
575 | /* | 600 | switch (offset) { |
576 | * Try to fix the alignment. This may result in a length | 601 | case 0: |
577 | * that is too large, so we must check for that. | 602 | /* Aligned */ |
578 | */ | 603 | break; |
579 | bytelen = get_hbp_len(info->ctrl.len); | 604 | case 1: |
580 | max_len = info->ctrl.type == ARM_BREAKPOINT_EXECUTE ? 4 : | 605 | /* Allow single byte watchpoint. */ |
581 | max_watchpoint_len; | 606 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) |
582 | 607 | break; | |
583 | if (max_len >= 8) | 608 | case 2: |
584 | offset = info->address & 0x7; | 609 | /* Allow halfword watchpoints and breakpoints. */ |
585 | else | 610 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_2) |
586 | offset = info->address & 0x3; | 611 | break; |
587 | 612 | default: | |
588 | if (bytelen > (1 << ((max_len - (offset + 1)) >> 1))) { | 613 | ret = -EINVAL; |
589 | ret = -EFBIG; | 614 | goto out; |
590 | goto out; | ||
591 | } | ||
592 | |||
593 | info->ctrl.len <<= offset; | ||
594 | info->address &= ~offset; | ||
595 | |||
596 | pr_debug("breakpoint alignment fixup: length = 0x%x, " | ||
597 | "address = 0x%x\n", info->ctrl.len, info->address); | ||
598 | } | 615 | } |
599 | 616 | ||
617 | info->address &= ~alignment_mask; | ||
618 | info->ctrl.len <<= offset; | ||
619 | |||
600 | /* | 620 | /* |
601 | * Currently we rely on an overflow handler to take | 621 | * Currently we rely on an overflow handler to take |
602 | * care of single-stepping the breakpoint when it fires. | 622 | * care of single-stepping the breakpoint when it fires. |
603 | * In the case of userspace breakpoints on a core with V7 debug, | 623 | * In the case of userspace breakpoints on a core with V7 debug, |
604 | * we can use the mismatch feature as a poor-man's hardware single-step. | 624 | * we can use the mismatch feature as a poor-man's hardware |
625 | * single-step, but this only works for per-task breakpoints. | ||
605 | */ | 626 | */ |
606 | if (WARN_ONCE(!bp->overflow_handler && | 627 | if (WARN_ONCE(!bp->overflow_handler && |
607 | (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_bps()), | 628 | (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps() |
629 | || !bp->hw.bp_target), | ||
608 | "overflow handler required but none found")) { | 630 | "overflow handler required but none found")) { |
609 | ret = -EINVAL; | 631 | ret = -EINVAL; |
610 | goto out; | ||
611 | } | 632 | } |
612 | out: | 633 | out: |
613 | return ret; | 634 | return ret; |
614 | } | 635 | } |
615 | 636 | ||
616 | static void update_mismatch_flag(int idx, int flag) | 637 | /* |
638 | * Enable/disable single-stepping over the breakpoint bp at address addr. | ||
639 | */ | ||
640 | static void enable_single_step(struct perf_event *bp, u32 addr) | ||
617 | { | 641 | { |
618 | struct perf_event *bp = __get_cpu_var(bp_on_reg[idx]); | 642 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
619 | struct arch_hw_breakpoint *info; | ||
620 | |||
621 | if (bp == NULL) | ||
622 | return; | ||
623 | 643 | ||
624 | info = counter_arch_bp(bp); | 644 | arch_uninstall_hw_breakpoint(bp); |
645 | info->step_ctrl.mismatch = 1; | ||
646 | info->step_ctrl.len = ARM_BREAKPOINT_LEN_4; | ||
647 | info->step_ctrl.type = ARM_BREAKPOINT_EXECUTE; | ||
648 | info->step_ctrl.privilege = info->ctrl.privilege; | ||
649 | info->step_ctrl.enabled = 1; | ||
650 | info->trigger = addr; | ||
651 | arch_install_hw_breakpoint(bp); | ||
652 | } | ||
625 | 653 | ||
626 | /* Update the mismatch field to enter/exit `single-step' mode */ | 654 | static void disable_single_step(struct perf_event *bp) |
627 | if (!bp->overflow_handler && info->ctrl.mismatch != flag) { | 655 | { |
628 | info->ctrl.mismatch = flag; | 656 | arch_uninstall_hw_breakpoint(bp); |
629 | write_wb_reg(ARM_BASE_BCR + idx, encode_ctrl_reg(info->ctrl) | 0x1); | 657 | counter_arch_bp(bp)->step_ctrl.enabled = 0; |
630 | } | 658 | arch_install_hw_breakpoint(bp); |
631 | } | 659 | } |
632 | 660 | ||
633 | static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | 661 | static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) |
634 | { | 662 | { |
635 | int i; | 663 | int i; |
636 | struct perf_event *bp, **slots = __get_cpu_var(wp_on_reg); | 664 | struct perf_event *wp, **slots; |
637 | struct arch_hw_breakpoint *info; | 665 | struct arch_hw_breakpoint *info; |
638 | struct perf_event_attr attr; | 666 | |
667 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
639 | 668 | ||
640 | /* Without a disassembler, we can only handle 1 watchpoint. */ | 669 | /* Without a disassembler, we can only handle 1 watchpoint. */ |
641 | BUG_ON(core_num_wrps > 1); | 670 | BUG_ON(core_num_wrps > 1); |
642 | 671 | ||
643 | hw_breakpoint_init(&attr); | ||
644 | attr.bp_addr = regs->ARM_pc & ~0x3; | ||
645 | attr.bp_len = HW_BREAKPOINT_LEN_4; | ||
646 | attr.bp_type = HW_BREAKPOINT_X; | ||
647 | |||
648 | for (i = 0; i < core_num_wrps; ++i) { | 672 | for (i = 0; i < core_num_wrps; ++i) { |
649 | rcu_read_lock(); | 673 | rcu_read_lock(); |
650 | 674 | ||
651 | if (slots[i] == NULL) { | 675 | wp = slots[i]; |
676 | |||
677 | if (wp == NULL) { | ||
652 | rcu_read_unlock(); | 678 | rcu_read_unlock(); |
653 | continue; | 679 | continue; |
654 | } | 680 | } |
@@ -658,24 +684,51 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | |||
658 | * single watchpoint, we can set the trigger to the lowest | 684 | * single watchpoint, we can set the trigger to the lowest |
659 | * possible faulting address. | 685 | * possible faulting address. |
660 | */ | 686 | */ |
661 | info = counter_arch_bp(slots[i]); | 687 | info = counter_arch_bp(wp); |
662 | info->trigger = slots[i]->attr.bp_addr; | 688 | info->trigger = wp->attr.bp_addr; |
663 | pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); | 689 | pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); |
664 | perf_bp_event(slots[i], regs); | 690 | perf_bp_event(wp, regs); |
665 | 691 | ||
666 | /* | 692 | /* |
667 | * If no overflow handler is present, insert a temporary | 693 | * If no overflow handler is present, insert a temporary |
668 | * mismatch breakpoint so we can single-step over the | 694 | * mismatch breakpoint so we can single-step over the |
669 | * watchpoint trigger. | 695 | * watchpoint trigger. |
670 | */ | 696 | */ |
671 | if (!slots[i]->overflow_handler) { | 697 | if (!wp->overflow_handler) |
672 | bp = register_user_hw_breakpoint(&attr, | 698 | enable_single_step(wp, instruction_pointer(regs)); |
673 | wp_single_step_handler, | 699 | |
674 | current); | 700 | rcu_read_unlock(); |
675 | counter_arch_bp(bp)->suspended_wp = slots[i]; | 701 | } |
676 | perf_event_disable(slots[i]); | 702 | } |
677 | } | ||
678 | 703 | ||
704 | static void watchpoint_single_step_handler(unsigned long pc) | ||
705 | { | ||
706 | int i; | ||
707 | struct perf_event *wp, **slots; | ||
708 | struct arch_hw_breakpoint *info; | ||
709 | |||
710 | slots = (struct perf_event **)__get_cpu_var(wp_on_reg); | ||
711 | |||
712 | for (i = 0; i < core_num_reserved_brps; ++i) { | ||
713 | rcu_read_lock(); | ||
714 | |||
715 | wp = slots[i]; | ||
716 | |||
717 | if (wp == NULL) | ||
718 | goto unlock; | ||
719 | |||
720 | info = counter_arch_bp(wp); | ||
721 | if (!info->step_ctrl.enabled) | ||
722 | goto unlock; | ||
723 | |||
724 | /* | ||
725 | * Restore the original watchpoint if we've completed the | ||
726 | * single-step. | ||
727 | */ | ||
728 | if (info->trigger != pc) | ||
729 | disable_single_step(wp); | ||
730 | |||
731 | unlock: | ||
679 | rcu_read_unlock(); | 732 | rcu_read_unlock(); |
680 | } | 733 | } |
681 | } | 734 | } |
@@ -683,62 +736,69 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | |||
683 | static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) | 736 | static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) |
684 | { | 737 | { |
685 | int i; | 738 | int i; |
686 | int mismatch; | ||
687 | u32 ctrl_reg, val, addr; | 739 | u32 ctrl_reg, val, addr; |
688 | struct perf_event *bp, **slots = __get_cpu_var(bp_on_reg); | 740 | struct perf_event *bp, **slots; |
689 | struct arch_hw_breakpoint *info; | 741 | struct arch_hw_breakpoint *info; |
690 | struct arch_hw_breakpoint_ctrl ctrl; | 742 | struct arch_hw_breakpoint_ctrl ctrl; |
691 | 743 | ||
744 | slots = (struct perf_event **)__get_cpu_var(bp_on_reg); | ||
745 | |||
692 | /* The exception entry code places the amended lr in the PC. */ | 746 | /* The exception entry code places the amended lr in the PC. */ |
693 | addr = regs->ARM_pc; | 747 | addr = regs->ARM_pc; |
694 | 748 | ||
749 | /* Check the currently installed breakpoints first. */ | ||
695 | for (i = 0; i < core_num_brps; ++i) { | 750 | for (i = 0; i < core_num_brps; ++i) { |
696 | rcu_read_lock(); | 751 | rcu_read_lock(); |
697 | 752 | ||
698 | bp = slots[i]; | 753 | bp = slots[i]; |
699 | 754 | ||
700 | if (bp == NULL) { | 755 | if (bp == NULL) |
701 | rcu_read_unlock(); | 756 | goto unlock; |
702 | continue; | ||
703 | } | ||
704 | 757 | ||
705 | mismatch = 0; | 758 | info = counter_arch_bp(bp); |
706 | 759 | ||
707 | /* Check if the breakpoint value matches. */ | 760 | /* Check if the breakpoint value matches. */ |
708 | val = read_wb_reg(ARM_BASE_BVR + i); | 761 | val = read_wb_reg(ARM_BASE_BVR + i); |
709 | if (val != (addr & ~0x3)) | 762 | if (val != (addr & ~0x3)) |
710 | goto unlock; | 763 | goto mismatch; |
711 | 764 | ||
712 | /* Possible match, check the byte address select to confirm. */ | 765 | /* Possible match, check the byte address select to confirm. */ |
713 | ctrl_reg = read_wb_reg(ARM_BASE_BCR + i); | 766 | ctrl_reg = read_wb_reg(ARM_BASE_BCR + i); |
714 | decode_ctrl_reg(ctrl_reg, &ctrl); | 767 | decode_ctrl_reg(ctrl_reg, &ctrl); |
715 | if ((1 << (addr & 0x3)) & ctrl.len) { | 768 | if ((1 << (addr & 0x3)) & ctrl.len) { |
716 | mismatch = 1; | ||
717 | info = counter_arch_bp(bp); | ||
718 | info->trigger = addr; | 769 | info->trigger = addr; |
719 | } | ||
720 | |||
721 | unlock: | ||
722 | if ((mismatch && !info->ctrl.mismatch) || bp_is_single_step(bp)) { | ||
723 | pr_debug("breakpoint fired: address = 0x%x\n", addr); | 770 | pr_debug("breakpoint fired: address = 0x%x\n", addr); |
724 | perf_bp_event(bp, regs); | 771 | perf_bp_event(bp, regs); |
772 | if (!bp->overflow_handler) | ||
773 | enable_single_step(bp, addr); | ||
774 | goto unlock; | ||
725 | } | 775 | } |
726 | 776 | ||
727 | update_mismatch_flag(i, mismatch); | 777 | mismatch: |
778 | /* If we're stepping a breakpoint, it can now be restored. */ | ||
779 | if (info->step_ctrl.enabled) | ||
780 | disable_single_step(bp); | ||
781 | unlock: | ||
728 | rcu_read_unlock(); | 782 | rcu_read_unlock(); |
729 | } | 783 | } |
784 | |||
785 | /* Handle any pending watchpoint single-step breakpoints. */ | ||
786 | watchpoint_single_step_handler(addr); | ||
730 | } | 787 | } |
731 | 788 | ||
732 | /* | 789 | /* |
733 | * Called from either the Data Abort Handler [watchpoint] or the | 790 | * Called from either the Data Abort Handler [watchpoint] or the |
734 | * Prefetch Abort Handler [breakpoint]. | 791 | * Prefetch Abort Handler [breakpoint] with preemption disabled. |
735 | */ | 792 | */ |
736 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | 793 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, |
737 | struct pt_regs *regs) | 794 | struct pt_regs *regs) |
738 | { | 795 | { |
739 | int ret = 1; /* Unhandled fault. */ | 796 | int ret = 0; |
740 | u32 dscr; | 797 | u32 dscr; |
741 | 798 | ||
799 | /* We must be called with preemption disabled. */ | ||
800 | WARN_ON(preemptible()); | ||
801 | |||
742 | /* We only handle watchpoints and hardware breakpoints. */ | 802 | /* We only handle watchpoints and hardware breakpoints. */ |
743 | ARM_DBG_READ(c1, 0, dscr); | 803 | ARM_DBG_READ(c1, 0, dscr); |
744 | 804 | ||
@@ -753,25 +813,47 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
753 | watchpoint_handler(addr, regs); | 813 | watchpoint_handler(addr, regs); |
754 | break; | 814 | break; |
755 | default: | 815 | default: |
756 | goto out; | 816 | ret = 1; /* Unhandled fault. */ |
757 | } | 817 | } |
758 | 818 | ||
759 | ret = 0; | 819 | /* |
760 | out: | 820 | * Re-enable preemption after it was disabled in the |
821 | * low-level exception handling code. | ||
822 | */ | ||
823 | preempt_enable(); | ||
824 | |||
761 | return ret; | 825 | return ret; |
762 | } | 826 | } |
763 | 827 | ||
764 | /* | 828 | /* |
765 | * One-time initialisation. | 829 | * One-time initialisation. |
766 | */ | 830 | */ |
767 | static void __init reset_ctrl_regs(void *unused) | 831 | static void reset_ctrl_regs(void *unused) |
768 | { | 832 | { |
769 | int i; | 833 | int i; |
770 | 834 | ||
835 | /* | ||
836 | * v7 debug contains save and restore registers so that debug state | ||
837 | * can be maintained across low-power modes without leaving | ||
838 | * the debug logic powered up. It is IMPLEMENTATION DEFINED whether | ||
839 | * we can write to the debug registers out of reset, so we must | ||
840 | * unlock the OS Lock Access Register to avoid taking undefined | ||
841 | * instruction exceptions later on. | ||
842 | */ | ||
843 | if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { | ||
844 | /* | ||
845 | * Unconditionally clear the lock by writing a value | ||
846 | * other than 0xC5ACCE55 to the access register. | ||
847 | */ | ||
848 | asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); | ||
849 | isb(); | ||
850 | } | ||
851 | |||
771 | if (enable_monitor_mode()) | 852 | if (enable_monitor_mode()) |
772 | return; | 853 | return; |
773 | 854 | ||
774 | for (i = 0; i < core_num_brps; ++i) { | 855 | /* We must also reset any reserved registers. */ |
856 | for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) { | ||
775 | write_wb_reg(ARM_BASE_BCR + i, 0UL); | 857 | write_wb_reg(ARM_BASE_BCR + i, 0UL); |
776 | write_wb_reg(ARM_BASE_BVR + i, 0UL); | 858 | write_wb_reg(ARM_BASE_BVR + i, 0UL); |
777 | } | 859 | } |
@@ -782,45 +864,57 @@ static void __init reset_ctrl_regs(void *unused) | |||
782 | } | 864 | } |
783 | } | 865 | } |
784 | 866 | ||
867 | static int __cpuinit dbg_reset_notify(struct notifier_block *self, | ||
868 | unsigned long action, void *cpu) | ||
869 | { | ||
870 | if (action == CPU_ONLINE) | ||
871 | smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1); | ||
872 | return NOTIFY_OK; | ||
873 | } | ||
874 | |||
875 | static struct notifier_block __cpuinitdata dbg_reset_nb = { | ||
876 | .notifier_call = dbg_reset_notify, | ||
877 | }; | ||
878 | |||
785 | static int __init arch_hw_breakpoint_init(void) | 879 | static int __init arch_hw_breakpoint_init(void) |
786 | { | 880 | { |
787 | int ret = 0; | ||
788 | u32 dscr; | 881 | u32 dscr; |
789 | 882 | ||
790 | debug_arch = get_debug_arch(); | 883 | debug_arch = get_debug_arch(); |
791 | 884 | ||
792 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { | 885 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { |
793 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); | 886 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); |
794 | ret = -ENODEV; | 887 | return 0; |
795 | goto out; | ||
796 | } | 888 | } |
797 | 889 | ||
798 | /* Determine how many BRPs/WRPs are available. */ | 890 | /* Determine how many BRPs/WRPs are available. */ |
799 | core_num_brps = get_num_brps(); | 891 | core_num_brps = get_num_brps(); |
892 | core_num_reserved_brps = get_num_reserved_brps(); | ||
800 | core_num_wrps = get_num_wrps(); | 893 | core_num_wrps = get_num_wrps(); |
801 | 894 | ||
802 | pr_info("found %d breakpoint and %d watchpoint registers.\n", | 895 | pr_info("found %d breakpoint and %d watchpoint registers.\n", |
803 | core_num_brps, core_num_wrps); | 896 | core_num_brps + core_num_reserved_brps, core_num_wrps); |
804 | 897 | ||
805 | if (core_has_mismatch_bps()) | 898 | if (core_num_reserved_brps) |
806 | pr_info("1 breakpoint reserved for watchpoint single-step.\n"); | 899 | pr_info("%d breakpoint(s) reserved for watchpoint " |
900 | "single-step.\n", core_num_reserved_brps); | ||
807 | 901 | ||
808 | ARM_DBG_READ(c1, 0, dscr); | 902 | ARM_DBG_READ(c1, 0, dscr); |
809 | if (dscr & ARM_DSCR_HDBGEN) { | 903 | if (dscr & ARM_DSCR_HDBGEN) { |
810 | pr_warning("halting debug mode enabled. Assuming maximum " | 904 | pr_warning("halting debug mode enabled. Assuming maximum " |
811 | "watchpoint size of 4 bytes."); | 905 | "watchpoint size of 4 bytes."); |
812 | } else { | 906 | } else { |
813 | /* Work out the maximum supported watchpoint length. */ | ||
814 | max_watchpoint_len = get_max_wp_len(); | ||
815 | pr_info("maximum watchpoint size is %u bytes.\n", | ||
816 | max_watchpoint_len); | ||
817 | |||
818 | /* | 907 | /* |
819 | * Reset the breakpoint resources. We assume that a halting | 908 | * Reset the breakpoint resources. We assume that a halting |
820 | * debugger will leave the world in a nice state for us. | 909 | * debugger will leave the world in a nice state for us. |
821 | */ | 910 | */ |
822 | smp_call_function(reset_ctrl_regs, NULL, 1); | 911 | smp_call_function(reset_ctrl_regs, NULL, 1); |
823 | reset_ctrl_regs(NULL); | 912 | reset_ctrl_regs(NULL); |
913 | |||
914 | /* Work out the maximum supported watchpoint length. */ | ||
915 | max_watchpoint_len = get_max_wp_len(); | ||
916 | pr_info("maximum watchpoint size is %u bytes.\n", | ||
917 | max_watchpoint_len); | ||
824 | } | 918 | } |
825 | 919 | ||
826 | /* Register debug fault handler. */ | 920 | /* Register debug fault handler. */ |
@@ -829,8 +923,9 @@ static int __init arch_hw_breakpoint_init(void) | |||
829 | hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, | 923 | hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, |
830 | "breakpoint debug exception"); | 924 | "breakpoint debug exception"); |
831 | 925 | ||
832 | out: | 926 | /* Register hotplug notifier. */ |
833 | return ret; | 927 | register_cpu_notifier(&dbg_reset_nb); |
928 | return 0; | ||
834 | } | 929 | } |
835 | arch_initcall(arch_hw_breakpoint_init); | 930 | arch_initcall(arch_hw_breakpoint_init); |
836 | 931 | ||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3e97483abcf..19c6816db61 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -1060,8 +1060,8 @@ static int ptrace_sethbpregs(struct task_struct *tsk, long num, | |||
1060 | goto out; | 1060 | goto out; |
1061 | 1061 | ||
1062 | if ((gen_type & implied_type) != gen_type) { | 1062 | if ((gen_type & implied_type) != gen_type) { |
1063 | ret = -EINVAL; | 1063 | ret = -EINVAL; |
1064 | goto out; | 1064 | goto out; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | attr.bp_len = gen_len; | 1067 | attr.bp_len = gen_len; |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index a40457d8192..c85923e56b8 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/time.h> | 31 | #include <linux/time.h> |
32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
33 | #include <linux/console.h> | ||
33 | 34 | ||
34 | #include <asm/mach/time.h> | 35 | #include <asm/mach/time.h> |
35 | #include <asm/mach/irq.h> | 36 | #include <asm/mach/irq.h> |
@@ -118,6 +119,10 @@ static void omap2_enter_full_retention(void) | |||
118 | if (omap_irq_pending()) | 119 | if (omap_irq_pending()) |
119 | goto no_sleep; | 120 | goto no_sleep; |
120 | 121 | ||
122 | /* Block console output in case it is on one of the OMAP UARTs */ | ||
123 | if (try_acquire_console_sem()) | ||
124 | goto no_sleep; | ||
125 | |||
121 | omap_uart_prepare_idle(0); | 126 | omap_uart_prepare_idle(0); |
122 | omap_uart_prepare_idle(1); | 127 | omap_uart_prepare_idle(1); |
123 | omap_uart_prepare_idle(2); | 128 | omap_uart_prepare_idle(2); |
@@ -131,6 +136,8 @@ static void omap2_enter_full_retention(void) | |||
131 | omap_uart_resume_idle(1); | 136 | omap_uart_resume_idle(1); |
132 | omap_uart_resume_idle(0); | 137 | omap_uart_resume_idle(0); |
133 | 138 | ||
139 | release_console_sem(); | ||
140 | |||
134 | no_sleep: | 141 | no_sleep: |
135 | if (omap2_pm_debug) { | 142 | if (omap2_pm_debug) { |
136 | unsigned long long tmp; | 143 | unsigned long long tmp; |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 75c0cd13ad8..0ec8a04b747 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/console.h> | ||
31 | 32 | ||
32 | #include <plat/sram.h> | 33 | #include <plat/sram.h> |
33 | #include <plat/clockdomain.h> | 34 | #include <plat/clockdomain.h> |
@@ -385,6 +386,12 @@ void omap_sram_idle(void) | |||
385 | omap3_enable_io_chain(); | 386 | omap3_enable_io_chain(); |
386 | } | 387 | } |
387 | 388 | ||
389 | /* Block console output in case it is on one of the OMAP UARTs */ | ||
390 | if (per_next_state < PWRDM_POWER_ON || | ||
391 | core_next_state < PWRDM_POWER_ON) | ||
392 | if (try_acquire_console_sem()) | ||
393 | goto console_still_active; | ||
394 | |||
388 | /* PER */ | 395 | /* PER */ |
389 | if (per_next_state < PWRDM_POWER_ON) { | 396 | if (per_next_state < PWRDM_POWER_ON) { |
390 | omap_uart_prepare_idle(2); | 397 | omap_uart_prepare_idle(2); |
@@ -463,6 +470,9 @@ void omap_sram_idle(void) | |||
463 | omap_uart_resume_idle(3); | 470 | omap_uart_resume_idle(3); |
464 | } | 471 | } |
465 | 472 | ||
473 | release_console_sem(); | ||
474 | |||
475 | console_still_active: | ||
466 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 476 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
467 | if (omap3_has_io_wakeup() && | 477 | if (omap3_has_io_wakeup() && |
468 | (per_next_state < PWRDM_POWER_ON || | 478 | (per_next_state < PWRDM_POWER_ON || |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index becf0e38ef7..d17960a1be2 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/serial_8250.h> | 28 | #include <linux/serial_8250.h> |
29 | #include <linux/pm_runtime.h> | 29 | #include <linux/pm_runtime.h> |
30 | #include <linux/console.h> | ||
30 | 31 | ||
31 | #ifdef CONFIG_SERIAL_OMAP | 32 | #ifdef CONFIG_SERIAL_OMAP |
32 | #include <plat/omap-serial.h> | 33 | #include <plat/omap-serial.h> |
@@ -406,7 +407,7 @@ void omap_uart_resume_idle(int num) | |||
406 | struct omap_uart_state *uart; | 407 | struct omap_uart_state *uart; |
407 | 408 | ||
408 | list_for_each_entry(uart, &uart_list, node) { | 409 | list_for_each_entry(uart, &uart_list, node) { |
409 | if (num == uart->num) { | 410 | if (num == uart->num && uart->can_sleep) { |
410 | omap_uart_enable_clocks(uart); | 411 | omap_uart_enable_clocks(uart); |
411 | 412 | ||
412 | /* Check for IO pad wakeup */ | 413 | /* Check for IO pad wakeup */ |
@@ -807,6 +808,8 @@ void __init omap_serial_init_port(int port) | |||
807 | 808 | ||
808 | oh->dev_attr = uart; | 809 | oh->dev_attr = uart; |
809 | 810 | ||
811 | acquire_console_sem(); /* in case the earlycon is on the UART */ | ||
812 | |||
810 | /* | 813 | /* |
811 | * Because of early UART probing, UART did not get idled | 814 | * Because of early UART probing, UART did not get idled |
812 | * on init. Now that omap_device is ready, ensure full idle | 815 | * on init. Now that omap_device is ready, ensure full idle |
@@ -831,6 +834,8 @@ void __init omap_serial_init_port(int port) | |||
831 | omap_uart_block_sleep(uart); | 834 | omap_uart_block_sleep(uart); |
832 | uart->timeout = DEFAULT_TIMEOUT; | 835 | uart->timeout = DEFAULT_TIMEOUT; |
833 | 836 | ||
837 | release_console_sem(); | ||
838 | |||
834 | if ((cpu_is_omap34xx() && uart->padconf) || | 839 | if ((cpu_is_omap34xx() && uart->padconf) || |
835 | (uart->wk_en && uart->wk_mask)) { | 840 | (uart->wk_en && uart->wk_mask)) { |
836 | device_init_wakeup(&od->pdev.dev, true); | 841 | device_init_wakeup(&od->pdev.dev, true); |
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c index 8aa2f1902a9..6b86a722a7d 100644 --- a/arch/arm/mach-s3c2410/h1940-bluetooth.c +++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c | |||
@@ -77,13 +77,13 @@ static int __devinit h1940bt_probe(struct platform_device *pdev) | |||
77 | 77 | ||
78 | /* Configures BT serial port GPIOs */ | 78 | /* Configures BT serial port GPIOs */ |
79 | s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); | 79 | s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); |
80 | s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); | 80 | s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); |
81 | s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); | 81 | s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); |
82 | s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); | 82 | s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); |
83 | s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); | 83 | s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); |
84 | s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); | 84 | s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); |
85 | s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); | 85 | s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); |
86 | s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); | 86 | s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); |
87 | 87 | ||
88 | 88 | ||
89 | rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, | 89 | rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, |
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c index 084d121f368..00174daf152 100644 --- a/arch/arm/mach-s3c2416/irq.c +++ b/arch/arm/mach-s3c2416/irq.c | |||
@@ -168,12 +168,11 @@ static struct irq_chip s3c2416_irq_dma = { | |||
168 | 168 | ||
169 | static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) | 169 | static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) |
170 | { | 170 | { |
171 | s3c2416_irq_demux(IRQ_S3C2443_UART3, 3); | 171 | s3c2416_irq_demux(IRQ_S3C2443_RX3, 3); |
172 | } | 172 | } |
173 | 173 | ||
174 | #define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) | 174 | #define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) |
175 | #define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) | 175 | #define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) |
176 | |||
177 | 176 | ||
178 | static void s3c2416_irq_uart3_mask(unsigned int irqno) | 177 | static void s3c2416_irq_uart3_mask(unsigned int irqno) |
179 | { | 178 | { |
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c index 0e0d693f397..893424767ce 100644 --- a/arch/arm/mach-s3c2443/irq.c +++ b/arch/arm/mach-s3c2443/irq.c | |||
@@ -166,12 +166,11 @@ static struct irq_chip s3c2443_irq_dma = { | |||
166 | 166 | ||
167 | static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) | 167 | static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) |
168 | { | 168 | { |
169 | s3c2443_irq_demux(IRQ_S3C2443_UART3, 3); | 169 | s3c2443_irq_demux(IRQ_S3C2443_RX3, 3); |
170 | } | 170 | } |
171 | 171 | ||
172 | #define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) | 172 | #define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) |
173 | #define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) | 173 | #define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) |
174 | |||
175 | 174 | ||
176 | static void s3c2443_irq_uart3_mask(unsigned int irqno) | 175 | static void s3c2443_irq_uart3_mask(unsigned int irqno) |
177 | { | 176 | { |
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index 249c6295647..89f35e02e88 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | #include <video/platform_lcd.h> | 46 | #include <video/platform_lcd.h> |
47 | 47 | ||
48 | #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) | 48 | #define UCON S3C2410_UCON_DEFAULT |
49 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) | 49 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) |
50 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) | 50 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) |
51 | 51 | ||
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index f9ef9b5c5f5..4957ab0a0d4 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | #include <video/platform_lcd.h> | 47 | #include <video/platform_lcd.h> |
48 | 48 | ||
49 | #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) | 49 | #define UCON S3C2410_UCON_DEFAULT |
50 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) | 50 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) |
51 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) | 51 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) |
52 | 52 | ||
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index 0ad7924fe62..5dd1681c069 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/serial_core.h> | 14 | #include <linux/serial_core.h> |
15 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
16 | #include <linux/sysdev.h> | ||
16 | 17 | ||
17 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
18 | #include <asm/mach/map.h> | 19 | #include <asm/mach/map.h> |
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index bcd7a5d5340..1fbc45b2a43 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/serial_core.h> | 15 | #include <linux/serial_core.h> |
16 | #include <linux/sysdev.h> | ||
16 | 17 | ||
17 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
18 | #include <asm/mach/map.h> | 19 | #include <asm/mach/map.h> |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index d3260542b94..d440e5f456a 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -567,38 +567,127 @@ static struct platform_device *qhd_devices[] __initdata = { | |||
567 | 567 | ||
568 | /* FSI */ | 568 | /* FSI */ |
569 | #define IRQ_FSI evt2irq(0x1840) | 569 | #define IRQ_FSI evt2irq(0x1840) |
570 | static int __fsi_set_rate(struct clk *clk, long rate, int enable) | ||
571 | { | ||
572 | int ret = 0; | ||
573 | |||
574 | if (rate <= 0) | ||
575 | return ret; | ||
576 | |||
577 | if (enable) { | ||
578 | ret = clk_set_rate(clk, rate); | ||
579 | if (0 == ret) | ||
580 | ret = clk_enable(clk); | ||
581 | } else { | ||
582 | clk_disable(clk); | ||
583 | } | ||
584 | |||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | static int __fsi_set_round_rate(struct clk *clk, long rate, int enable) | ||
589 | { | ||
590 | return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable); | ||
591 | } | ||
570 | 592 | ||
571 | static int fsi_set_rate(int is_porta, int rate) | 593 | static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable) |
594 | { | ||
595 | struct clk *fsia_ick; | ||
596 | struct clk *fsiack; | ||
597 | int ret = -EIO; | ||
598 | |||
599 | fsia_ick = clk_get(dev, "icka"); | ||
600 | if (IS_ERR(fsia_ick)) | ||
601 | return PTR_ERR(fsia_ick); | ||
602 | |||
603 | /* | ||
604 | * FSIACK is connected to AK4642, | ||
605 | * and use external clock pin from it. | ||
606 | * it is parent of fsia_ick now. | ||
607 | */ | ||
608 | fsiack = clk_get_parent(fsia_ick); | ||
609 | if (!fsiack) | ||
610 | goto fsia_ick_out; | ||
611 | |||
612 | /* | ||
613 | * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick | ||
614 | * | ||
615 | ** FIXME ** | ||
616 | * Because the freq_table of external clk (fsiack) are all 0, | ||
617 | * the return value of clk_round_rate became 0. | ||
618 | * So, it use __fsi_set_rate here. | ||
619 | */ | ||
620 | ret = __fsi_set_rate(fsiack, rate, enable); | ||
621 | if (ret < 0) | ||
622 | goto fsiack_out; | ||
623 | |||
624 | ret = __fsi_set_round_rate(fsia_ick, rate, enable); | ||
625 | if ((ret < 0) && enable) | ||
626 | __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */ | ||
627 | |||
628 | fsiack_out: | ||
629 | clk_put(fsiack); | ||
630 | |||
631 | fsia_ick_out: | ||
632 | clk_put(fsia_ick); | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable) | ||
572 | { | 638 | { |
573 | struct clk *fsib_clk; | 639 | struct clk *fsib_clk; |
574 | struct clk *fdiv_clk = &sh7372_fsidivb_clk; | 640 | struct clk *fdiv_clk = &sh7372_fsidivb_clk; |
641 | long fsib_rate = 0; | ||
642 | long fdiv_rate = 0; | ||
643 | int ackmd_bpfmd; | ||
575 | int ret; | 644 | int ret; |
576 | 645 | ||
577 | /* set_rate is not needed if port A */ | ||
578 | if (is_porta) | ||
579 | return 0; | ||
580 | |||
581 | fsib_clk = clk_get(NULL, "fsib_clk"); | ||
582 | if (IS_ERR(fsib_clk)) | ||
583 | return -EINVAL; | ||
584 | |||
585 | switch (rate) { | 646 | switch (rate) { |
586 | case 44100: | 647 | case 44100: |
587 | clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); | 648 | fsib_rate = rate * 256; |
588 | ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; | 649 | ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; |
589 | break; | 650 | break; |
590 | case 48000: | 651 | case 48000: |
591 | clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); | 652 | fsib_rate = 85428000; /* around 48kHz x 256 x 7 */ |
592 | clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); | 653 | fdiv_rate = rate * 256; |
593 | ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; | 654 | ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; |
594 | break; | 655 | break; |
595 | default: | 656 | default: |
596 | pr_err("unsupported rate in FSI2 port B\n"); | 657 | pr_err("unsupported rate in FSI2 port B\n"); |
597 | ret = -EINVAL; | 658 | return -EINVAL; |
598 | break; | ||
599 | } | 659 | } |
600 | 660 | ||
661 | /* FSI B setting */ | ||
662 | fsib_clk = clk_get(dev, "ickb"); | ||
663 | if (IS_ERR(fsib_clk)) | ||
664 | return -EIO; | ||
665 | |||
666 | ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable); | ||
601 | clk_put(fsib_clk); | 667 | clk_put(fsib_clk); |
668 | if (ret < 0) | ||
669 | return ret; | ||
670 | |||
671 | /* FSI DIV setting */ | ||
672 | ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable); | ||
673 | if (ret < 0) { | ||
674 | /* disable FSI B */ | ||
675 | if (enable) | ||
676 | __fsi_set_round_rate(fsib_clk, fsib_rate, 0); | ||
677 | return ret; | ||
678 | } | ||
679 | |||
680 | return ackmd_bpfmd; | ||
681 | } | ||
682 | |||
683 | static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) | ||
684 | { | ||
685 | int ret; | ||
686 | |||
687 | if (is_porta) | ||
688 | ret = fsi_ak4642_set_rate(dev, rate, enable); | ||
689 | else | ||
690 | ret = fsi_hdmi_set_rate(dev, rate, enable); | ||
602 | 691 | ||
603 | return ret; | 692 | return ret; |
604 | } | 693 | } |
@@ -880,6 +969,11 @@ static int __init hdmi_init_pm_clock(void) | |||
880 | goto out; | 969 | goto out; |
881 | } | 970 | } |
882 | 971 | ||
972 | ret = clk_enable(&sh7372_pllc2_clk); | ||
973 | if (ret < 0) { | ||
974 | pr_err("Cannot enable pllc2 clock\n"); | ||
975 | goto out; | ||
976 | } | ||
883 | pr_debug("PLLC2 set frequency %lu\n", rate); | 977 | pr_debug("PLLC2 set frequency %lu\n", rate); |
884 | 978 | ||
885 | ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); | 979 | ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); |
@@ -896,23 +990,11 @@ out: | |||
896 | 990 | ||
897 | device_initcall(hdmi_init_pm_clock); | 991 | device_initcall(hdmi_init_pm_clock); |
898 | 992 | ||
899 | #define FSIACK_DUMMY_RATE 48000 | ||
900 | static int __init fsi_init_pm_clock(void) | 993 | static int __init fsi_init_pm_clock(void) |
901 | { | 994 | { |
902 | struct clk *fsia_ick; | 995 | struct clk *fsia_ick; |
903 | int ret; | 996 | int ret; |
904 | 997 | ||
905 | /* | ||
906 | * FSIACK is connected to AK4642, | ||
907 | * and the rate is depend on playing sound rate. | ||
908 | * So, set dummy rate (= 48k) here | ||
909 | */ | ||
910 | ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE); | ||
911 | if (ret < 0) { | ||
912 | pr_err("Cannot set FSIACK dummy rate: %d\n", ret); | ||
913 | return ret; | ||
914 | } | ||
915 | |||
916 | fsia_ick = clk_get(&fsi_device.dev, "icka"); | 998 | fsia_ick = clk_get(&fsi_device.dev, "icka"); |
917 | if (IS_ERR(fsia_ick)) { | 999 | if (IS_ERR(fsia_ick)) { |
918 | ret = PTR_ERR(fsia_ick); | 1000 | ret = PTR_ERR(fsia_ick); |
@@ -921,16 +1003,9 @@ static int __init fsi_init_pm_clock(void) | |||
921 | } | 1003 | } |
922 | 1004 | ||
923 | ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); | 1005 | ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); |
924 | if (ret < 0) { | ||
925 | pr_err("Cannot set FSI-A parent: %d\n", ret); | ||
926 | goto out; | ||
927 | } | ||
928 | |||
929 | ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE); | ||
930 | if (ret < 0) | 1006 | if (ret < 0) |
931 | pr_err("Cannot set FSI-A rate: %d\n", ret); | 1007 | pr_err("Cannot set FSI-A parent: %d\n", ret); |
932 | 1008 | ||
933 | out: | ||
934 | clk_put(fsia_ick); | 1009 | clk_put(fsia_ick); |
935 | 1010 | ||
936 | return ret; | 1011 | return ret; |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index b25ce90a346..3aa02606943 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -229,21 +229,13 @@ static int pllc2_set_rate(struct clk *clk, unsigned long rate) | |||
229 | if (idx < 0) | 229 | if (idx < 0) |
230 | return idx; | 230 | return idx; |
231 | 231 | ||
232 | if (rate == clk->parent->rate) { | 232 | if (rate == clk->parent->rate) |
233 | pllc2_disable(clk); | 233 | return -EINVAL; |
234 | return 0; | ||
235 | } | ||
236 | 234 | ||
237 | value = __raw_readl(PLLC2CR) & ~(0x3f << 24); | 235 | value = __raw_readl(PLLC2CR) & ~(0x3f << 24); |
238 | 236 | ||
239 | if (value & 0x80000000) | ||
240 | pllc2_disable(clk); | ||
241 | |||
242 | __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR); | 237 | __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR); |
243 | 238 | ||
244 | if (value & 0x80000000) | ||
245 | return pllc2_enable(clk); | ||
246 | |||
247 | return 0; | 239 | return 0; |
248 | } | 240 | } |
249 | 241 | ||
@@ -452,10 +444,8 @@ static int fsidiv_enable(struct clk *clk) | |||
452 | unsigned long value; | 444 | unsigned long value; |
453 | 445 | ||
454 | value = __raw_readl(clk->mapping->base) >> 16; | 446 | value = __raw_readl(clk->mapping->base) >> 16; |
455 | if (value < 2) { | 447 | if (value < 2) |
456 | fsidiv_disable(clk); | 448 | return -EIO; |
457 | return -ENOENT; | ||
458 | } | ||
459 | 449 | ||
460 | __raw_writel((value << 16) | 0x3, clk->mapping->base); | 450 | __raw_writel((value << 16) | 0x3, clk->mapping->base); |
461 | 451 | ||
@@ -466,17 +456,12 @@ static int fsidiv_set_rate(struct clk *clk, unsigned long rate) | |||
466 | { | 456 | { |
467 | int idx; | 457 | int idx; |
468 | 458 | ||
469 | if (clk->parent->rate == rate) { | ||
470 | fsidiv_disable(clk); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | idx = (clk->parent->rate / rate) & 0xffff; | 459 | idx = (clk->parent->rate / rate) & 0xffff; |
475 | if (idx < 2) | 460 | if (idx < 2) |
476 | return -ENOENT; | 461 | return -EINVAL; |
477 | 462 | ||
478 | __raw_writel(idx << 16, clk->mapping->base); | 463 | __raw_writel(idx << 16, clk->mapping->base); |
479 | return fsidiv_enable(clk); | 464 | return 0; |
480 | } | 465 | } |
481 | 466 | ||
482 | static struct clk_ops fsidiv_clk_ops = { | 467 | static struct clk_ops fsidiv_clk_ops = { |
@@ -607,8 +592,6 @@ static struct clk_lookup lookups[] = { | |||
607 | CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), | 592 | CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), |
608 | CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), | 593 | CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), |
609 | CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), | 594 | CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), |
610 | CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]), | ||
611 | CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]), | ||
612 | CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), | 595 | CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), |
613 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), | 596 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), |
614 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), | 597 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), |
@@ -645,8 +628,8 @@ static struct clk_lookup lookups[] = { | |||
645 | CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ | 628 | CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ |
646 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ | 629 | CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ |
647 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ | 630 | CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ |
648 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */ | 631 | CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ |
649 | CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */ | 632 | CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */ |
650 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ | 633 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ |
651 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ | 634 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ |
652 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ | 635 | CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ |
diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h index e49c5b6fc4e..1ab332e37d7 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/arch/arm/plat-pxa/include/plat/sdhci.h | |||
@@ -17,6 +17,9 @@ | |||
17 | /* Require clock free running */ | 17 | /* Require clock free running */ |
18 | #define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0) | 18 | #define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0) |
19 | 19 | ||
20 | /* Board design supports 8-bit data on SD/SDIO BUS */ | ||
21 | #define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2) | ||
22 | |||
20 | /* | 23 | /* |
21 | * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI | 24 | * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI |
22 | * @max_speed: the maximum speed supported | 25 | * @max_speed: the maximum speed supported |
diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c index 9793544a6ac..704175b0573 100644 --- a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c +++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c | |||
@@ -29,8 +29,8 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi, | |||
29 | } else { | 29 | } else { |
30 | s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); | 30 | s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT); |
31 | s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); | 31 | s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT); |
32 | s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE); | 32 | s3c_gpio_setpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE); |
33 | s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE); | 33 | s3c_gpio_setpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE); |
34 | s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE); | 34 | s3c_gpio_setpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE); |
35 | } | 35 | } |
36 | } | 36 | } |
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c index db9e9e477ec..72457afd625 100644 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c +++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c | |||
@@ -31,8 +31,8 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, | |||
31 | } else { | 31 | } else { |
32 | s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); | 32 | s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); |
33 | s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); | 33 | s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); |
34 | s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE); | 34 | s3c_gpio_setpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE); |
35 | s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE); | 35 | s3c_gpio_setpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE); |
36 | s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE); | 36 | s3c_gpio_setpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE); |
37 | } | 37 | } |
38 | } | 38 | } |
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c index 8ea663a438b..c3972b645d1 100644 --- a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c +++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c | |||
@@ -29,8 +29,8 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, | |||
29 | } else { | 29 | } else { |
30 | s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); | 30 | s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT); |
31 | s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); | 31 | s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT); |
32 | s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE); | 32 | s3c_gpio_setpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE); |
33 | s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE); | 33 | s3c_gpio_setpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE); |
34 | s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE); | 34 | s3c_gpio_setpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE); |
35 | } | 35 | } |
36 | } | 36 | } |