diff options
Diffstat (limited to 'arch/mips/au1000/common')
-rw-r--r-- | arch/mips/au1000/common/dbdma.c | 2 | ||||
-rw-r--r-- | arch/mips/au1000/common/irq.c | 63 | ||||
-rw-r--r-- | arch/mips/au1000/common/prom.c | 2 | ||||
-rw-r--r-- | arch/mips/au1000/common/setup.c | 2 | ||||
-rw-r--r-- | arch/mips/au1000/common/time.c | 106 |
5 files changed, 27 insertions, 148 deletions
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index c4fae8ff4671..626de44bd888 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c | |||
@@ -849,7 +849,7 @@ au1xxx_dbdma_chan_free(u32 chanid) | |||
849 | EXPORT_SYMBOL(au1xxx_dbdma_chan_free); | 849 | EXPORT_SYMBOL(au1xxx_dbdma_chan_free); |
850 | 850 | ||
851 | static irqreturn_t | 851 | static irqreturn_t |
852 | dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 852 | dbdma_interrupt(int irq, void *dev_id) |
853 | { | 853 | { |
854 | u32 intstat; | 854 | u32 intstat; |
855 | u32 chan_index; | 855 | u32 chan_index; |
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index 2abe132bb07d..9cf7b6715836 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c | |||
@@ -70,7 +70,6 @@ extern irq_cpustat_t irq_stat [NR_CPUS]; | |||
70 | extern void mips_timer_interrupt(void); | 70 | extern void mips_timer_interrupt(void); |
71 | 71 | ||
72 | static void setup_local_irq(unsigned int irq, int type, int int_req); | 72 | static void setup_local_irq(unsigned int irq, int type, int int_req); |
73 | static unsigned int startup_irq(unsigned int irq); | ||
74 | static void end_irq(unsigned int irq_nr); | 73 | static void end_irq(unsigned int irq_nr); |
75 | static inline void mask_and_ack_level_irq(unsigned int irq_nr); | 74 | static inline void mask_and_ack_level_irq(unsigned int irq_nr); |
76 | static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr); | 75 | static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr); |
@@ -84,20 +83,6 @@ void (*board_init_irq)(void); | |||
84 | static DEFINE_SPINLOCK(irq_lock); | 83 | static DEFINE_SPINLOCK(irq_lock); |
85 | 84 | ||
86 | 85 | ||
87 | static unsigned int startup_irq(unsigned int irq_nr) | ||
88 | { | ||
89 | local_enable_irq(irq_nr); | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | |||
94 | static void shutdown_irq(unsigned int irq_nr) | ||
95 | { | ||
96 | local_disable_irq(irq_nr); | ||
97 | return; | ||
98 | } | ||
99 | |||
100 | |||
101 | inline void local_enable_irq(unsigned int irq_nr) | 86 | inline void local_enable_irq(unsigned int irq_nr) |
102 | { | 87 | { |
103 | if (irq_nr > AU1000_LAST_INTC0_INT) { | 88 | if (irq_nr > AU1000_LAST_INTC0_INT) { |
@@ -249,41 +234,37 @@ void restore_local_and_enable(int controller, unsigned long mask) | |||
249 | 234 | ||
250 | static struct irq_chip rise_edge_irq_type = { | 235 | static struct irq_chip rise_edge_irq_type = { |
251 | .typename = "Au1000 Rise Edge", | 236 | .typename = "Au1000 Rise Edge", |
252 | .startup = startup_irq, | ||
253 | .shutdown = shutdown_irq, | ||
254 | .enable = local_enable_irq, | ||
255 | .disable = local_disable_irq, | ||
256 | .ack = mask_and_ack_rise_edge_irq, | 237 | .ack = mask_and_ack_rise_edge_irq, |
238 | .mask = local_disable_irq, | ||
239 | .mask_ack = mask_and_ack_rise_edge_irq, | ||
240 | .unmask = local_enable_irq, | ||
257 | .end = end_irq, | 241 | .end = end_irq, |
258 | }; | 242 | }; |
259 | 243 | ||
260 | static struct irq_chip fall_edge_irq_type = { | 244 | static struct irq_chip fall_edge_irq_type = { |
261 | .typename = "Au1000 Fall Edge", | 245 | .typename = "Au1000 Fall Edge", |
262 | .startup = startup_irq, | ||
263 | .shutdown = shutdown_irq, | ||
264 | .enable = local_enable_irq, | ||
265 | .disable = local_disable_irq, | ||
266 | .ack = mask_and_ack_fall_edge_irq, | 246 | .ack = mask_and_ack_fall_edge_irq, |
247 | .mask = local_disable_irq, | ||
248 | .mask_ack = mask_and_ack_fall_edge_irq, | ||
249 | .unmask = local_enable_irq, | ||
267 | .end = end_irq, | 250 | .end = end_irq, |
268 | }; | 251 | }; |
269 | 252 | ||
270 | static struct irq_chip either_edge_irq_type = { | 253 | static struct irq_chip either_edge_irq_type = { |
271 | .typename = "Au1000 Rise or Fall Edge", | 254 | .typename = "Au1000 Rise or Fall Edge", |
272 | .startup = startup_irq, | ||
273 | .shutdown = shutdown_irq, | ||
274 | .enable = local_enable_irq, | ||
275 | .disable = local_disable_irq, | ||
276 | .ack = mask_and_ack_either_edge_irq, | 255 | .ack = mask_and_ack_either_edge_irq, |
256 | .mask = local_disable_irq, | ||
257 | .mask_ack = mask_and_ack_either_edge_irq, | ||
258 | .unmask = local_enable_irq, | ||
277 | .end = end_irq, | 259 | .end = end_irq, |
278 | }; | 260 | }; |
279 | 261 | ||
280 | static struct irq_chip level_irq_type = { | 262 | static struct irq_chip level_irq_type = { |
281 | .typename = "Au1000 Level", | 263 | .typename = "Au1000 Level", |
282 | .startup = startup_irq, | ||
283 | .shutdown = shutdown_irq, | ||
284 | .enable = local_enable_irq, | ||
285 | .disable = local_disable_irq, | ||
286 | .ack = mask_and_ack_level_irq, | 264 | .ack = mask_and_ack_level_irq, |
265 | .mask = local_disable_irq, | ||
266 | .mask_ack = mask_and_ack_level_irq, | ||
267 | .unmask = local_enable_irq, | ||
287 | .end = end_irq, | 268 | .end = end_irq, |
288 | }; | 269 | }; |
289 | 270 | ||
@@ -328,31 +309,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) | |||
328 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 309 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); |
329 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 310 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); |
330 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 311 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); |
331 | irq_desc[irq_nr].chip = &rise_edge_irq_type; | 312 | set_irq_chip(irq_nr, &rise_edge_irq_type); |
332 | break; | 313 | break; |
333 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | 314 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ |
334 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 315 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); |
335 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 316 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); |
336 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 317 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); |
337 | irq_desc[irq_nr].chip = &fall_edge_irq_type; | 318 | set_irq_chip(irq_nr, &fall_edge_irq_type); |
338 | break; | 319 | break; |
339 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | 320 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ |
340 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); | 321 | au_writel(1<<(irq_nr-32), IC1_CFG2CLR); |
341 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 322 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); |
342 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 323 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); |
343 | irq_desc[irq_nr].chip = &either_edge_irq_type; | 324 | set_irq_chip(irq_nr, &either_edge_irq_type); |
344 | break; | 325 | break; |
345 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | 326 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ |
346 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); | 327 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); |
347 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); | 328 | au_writel(1<<(irq_nr-32), IC1_CFG1CLR); |
348 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); | 329 | au_writel(1<<(irq_nr-32), IC1_CFG0SET); |
349 | irq_desc[irq_nr].chip = &level_irq_type; | 330 | set_irq_chip(irq_nr, &level_irq_type); |
350 | break; | 331 | break; |
351 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | 332 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ |
352 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); | 333 | au_writel(1<<(irq_nr-32), IC1_CFG2SET); |
353 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); | 334 | au_writel(1<<(irq_nr-32), IC1_CFG1SET); |
354 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 335 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); |
355 | irq_desc[irq_nr].chip = &level_irq_type; | 336 | set_irq_chip(irq_nr, &level_irq_type); |
356 | break; | 337 | break; |
357 | case INTC_INT_DISABLED: /* 0:0:0 */ | 338 | case INTC_INT_DISABLED: /* 0:0:0 */ |
358 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); | 339 | au_writel(1<<(irq_nr-32), IC1_CFG0CLR); |
@@ -380,31 +361,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) | |||
380 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 361 | au_writel(1<<irq_nr, IC0_CFG2CLR); |
381 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 362 | au_writel(1<<irq_nr, IC0_CFG1CLR); |
382 | au_writel(1<<irq_nr, IC0_CFG0SET); | 363 | au_writel(1<<irq_nr, IC0_CFG0SET); |
383 | irq_desc[irq_nr].chip = &rise_edge_irq_type; | 364 | set_irq_chip(irq_nr, &rise_edge_irq_type); |
384 | break; | 365 | break; |
385 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | 366 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ |
386 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 367 | au_writel(1<<irq_nr, IC0_CFG2CLR); |
387 | au_writel(1<<irq_nr, IC0_CFG1SET); | 368 | au_writel(1<<irq_nr, IC0_CFG1SET); |
388 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 369 | au_writel(1<<irq_nr, IC0_CFG0CLR); |
389 | irq_desc[irq_nr].chip = &fall_edge_irq_type; | 370 | set_irq_chip(irq_nr, &fall_edge_irq_type); |
390 | break; | 371 | break; |
391 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | 372 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ |
392 | au_writel(1<<irq_nr, IC0_CFG2CLR); | 373 | au_writel(1<<irq_nr, IC0_CFG2CLR); |
393 | au_writel(1<<irq_nr, IC0_CFG1SET); | 374 | au_writel(1<<irq_nr, IC0_CFG1SET); |
394 | au_writel(1<<irq_nr, IC0_CFG0SET); | 375 | au_writel(1<<irq_nr, IC0_CFG0SET); |
395 | irq_desc[irq_nr].chip = &either_edge_irq_type; | 376 | set_irq_chip(irq_nr, &either_edge_irq_type); |
396 | break; | 377 | break; |
397 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | 378 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ |
398 | au_writel(1<<irq_nr, IC0_CFG2SET); | 379 | au_writel(1<<irq_nr, IC0_CFG2SET); |
399 | au_writel(1<<irq_nr, IC0_CFG1CLR); | 380 | au_writel(1<<irq_nr, IC0_CFG1CLR); |
400 | au_writel(1<<irq_nr, IC0_CFG0SET); | 381 | au_writel(1<<irq_nr, IC0_CFG0SET); |
401 | irq_desc[irq_nr].chip = &level_irq_type; | 382 | set_irq_chip(irq_nr, &level_irq_type); |
402 | break; | 383 | break; |
403 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | 384 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ |
404 | au_writel(1<<irq_nr, IC0_CFG2SET); | 385 | au_writel(1<<irq_nr, IC0_CFG2SET); |
405 | au_writel(1<<irq_nr, IC0_CFG1SET); | 386 | au_writel(1<<irq_nr, IC0_CFG1SET); |
406 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 387 | au_writel(1<<irq_nr, IC0_CFG0CLR); |
407 | irq_desc[irq_nr].chip = &level_irq_type; | 388 | set_irq_chip(irq_nr, &level_irq_type); |
408 | break; | 389 | break; |
409 | case INTC_INT_DISABLED: /* 0:0:0 */ | 390 | case INTC_INT_DISABLED: /* 0:0:0 */ |
410 | au_writel(1<<irq_nr, IC0_CFG0CLR); | 391 | au_writel(1<<irq_nr, IC0_CFG0CLR); |
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index b4b010a2fe36..6fce60af005d 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c | |||
@@ -47,7 +47,7 @@ extern int prom_argc; | |||
47 | extern char **prom_argv, **prom_envp; | 47 | extern char **prom_argv, **prom_envp; |
48 | 48 | ||
49 | 49 | ||
50 | char * prom_getcmdline(void) | 50 | char * __init_or_module prom_getcmdline(void) |
51 | { | 51 | { |
52 | return &(arcs_cmdline[0]); | 52 | return &(arcs_cmdline[0]); |
53 | } | 53 | } |
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 377ae0d8ff00..919172db560c 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <asm/mach-au1x00/au1000.h> | 43 | #include <asm/mach-au1x00/au1000.h> |
44 | #include <asm/time.h> | 44 | #include <asm/time.h> |
45 | 45 | ||
46 | extern char * __init prom_getcmdline(void); | 46 | extern char * prom_getcmdline(void); |
47 | extern void __init board_setup(void); | 47 | extern void __init board_setup(void); |
48 | extern void au1000_restart(char *); | 48 | extern void au1000_restart(char *); |
49 | extern void au1000_halt(void); | 49 | extern void au1000_halt(void); |
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 94f09194d63d..fa1c62f05515 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c | |||
@@ -53,9 +53,6 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */ | |||
53 | int no_au1xxx_32khz; | 53 | int no_au1xxx_32khz; |
54 | extern int allow_au1k_wait; /* default off for CP0 Counter */ | 54 | extern int allow_au1k_wait; /* default off for CP0 Counter */ |
55 | 55 | ||
56 | /* Cycle counter value at the previous timer interrupt.. */ | ||
57 | static unsigned int timerhi = 0, timerlo = 0; | ||
58 | |||
59 | #ifdef CONFIG_PM | 56 | #ifdef CONFIG_PM |
60 | #if HZ < 100 || HZ > 1000 | 57 | #if HZ < 100 || HZ > 1000 |
61 | #error "unsupported HZ value! Must be in [100,1000]" | 58 | #error "unsupported HZ value! Must be in [100,1000]" |
@@ -82,7 +79,6 @@ unsigned long wtimer; | |||
82 | void mips_timer_interrupt(void) | 79 | void mips_timer_interrupt(void) |
83 | { | 80 | { |
84 | int irq = 63; | 81 | int irq = 63; |
85 | unsigned long count; | ||
86 | 82 | ||
87 | irq_enter(); | 83 | irq_enter(); |
88 | kstat_this_cpu.irqs[irq]++; | 84 | kstat_this_cpu.irqs[irq]++; |
@@ -91,10 +87,6 @@ void mips_timer_interrupt(void) | |||
91 | goto null; | 87 | goto null; |
92 | 88 | ||
93 | do { | 89 | do { |
94 | count = read_c0_count(); | ||
95 | timerhi += (count < timerlo); /* Wrap around */ | ||
96 | timerlo = count; | ||
97 | |||
98 | kstat_this_cpu.irqs[irq]++; | 90 | kstat_this_cpu.irqs[irq]++; |
99 | do_timer(1); | 91 | do_timer(1); |
100 | #ifndef CONFIG_SMP | 92 | #ifndef CONFIG_SMP |
@@ -231,7 +223,6 @@ wakeup_counter0_set(int ticks) | |||
231 | */ | 223 | */ |
232 | unsigned long cal_r4koff(void) | 224 | unsigned long cal_r4koff(void) |
233 | { | 225 | { |
234 | unsigned long count; | ||
235 | unsigned long cpu_speed; | 226 | unsigned long cpu_speed; |
236 | unsigned long flags; | 227 | unsigned long flags; |
237 | unsigned long counter; | 228 | unsigned long counter; |
@@ -258,7 +249,7 @@ unsigned long cal_r4koff(void) | |||
258 | 249 | ||
259 | #if defined(CONFIG_AU1000_USE32K) | 250 | #if defined(CONFIG_AU1000_USE32K) |
260 | { | 251 | { |
261 | unsigned long start, end; | 252 | unsigned long start, end, count; |
262 | 253 | ||
263 | start = au_readl(SYS_RTCREAD); | 254 | start = au_readl(SYS_RTCREAD); |
264 | start += 2; | 255 | start += 2; |
@@ -282,7 +273,6 @@ unsigned long cal_r4koff(void) | |||
282 | #else | 273 | #else |
283 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * | 274 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * |
284 | AU1000_SRC_CLK; | 275 | AU1000_SRC_CLK; |
285 | count = cpu_speed / 2; | ||
286 | #endif | 276 | #endif |
287 | } | 277 | } |
288 | else { | 278 | else { |
@@ -291,98 +281,15 @@ unsigned long cal_r4koff(void) | |||
291 | * NOTE: some old silicon doesn't allow reading the PLL. | 281 | * NOTE: some old silicon doesn't allow reading the PLL. |
292 | */ | 282 | */ |
293 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; | 283 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; |
294 | count = cpu_speed / 2; | ||
295 | no_au1xxx_32khz = 1; | 284 | no_au1xxx_32khz = 1; |
296 | } | 285 | } |
297 | mips_hpt_frequency = count; | 286 | mips_hpt_frequency = cpu_speed; |
298 | // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) | 287 | // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) |
299 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); | 288 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); |
300 | spin_unlock_irqrestore(&time_lock, flags); | 289 | spin_unlock_irqrestore(&time_lock, flags); |
301 | return (cpu_speed / HZ); | 290 | return (cpu_speed / HZ); |
302 | } | 291 | } |
303 | 292 | ||
304 | /* This is for machines which generate the exact clock. */ | ||
305 | #define USECS_PER_JIFFY (1000000/HZ) | ||
306 | #define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff) | ||
307 | |||
308 | static unsigned long | ||
309 | div64_32(unsigned long v1, unsigned long v2, unsigned long v3) | ||
310 | { | ||
311 | unsigned long r0; | ||
312 | do_div64_32(r0, v1, v2, v3); | ||
313 | return r0; | ||
314 | } | ||
315 | |||
316 | static unsigned long do_fast_cp0_gettimeoffset(void) | ||
317 | { | ||
318 | u32 count; | ||
319 | unsigned long res, tmp; | ||
320 | unsigned long r0; | ||
321 | |||
322 | /* Last jiffy when do_fast_gettimeoffset() was called. */ | ||
323 | static unsigned long last_jiffies=0; | ||
324 | unsigned long quotient; | ||
325 | |||
326 | /* | ||
327 | * Cached "1/(clocks per usec)*2^32" value. | ||
328 | * It has to be recalculated once each jiffy. | ||
329 | */ | ||
330 | static unsigned long cached_quotient=0; | ||
331 | |||
332 | tmp = jiffies; | ||
333 | |||
334 | quotient = cached_quotient; | ||
335 | |||
336 | if (tmp && last_jiffies != tmp) { | ||
337 | last_jiffies = tmp; | ||
338 | if (last_jiffies != 0) { | ||
339 | r0 = div64_32(timerhi, timerlo, tmp); | ||
340 | quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); | ||
341 | cached_quotient = quotient; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | /* Get last timer tick in absolute kernel time */ | ||
346 | count = read_c0_count(); | ||
347 | |||
348 | /* .. relative to previous jiffy (32 bits is enough) */ | ||
349 | count -= timerlo; | ||
350 | |||
351 | __asm__("multu\t%1,%2\n\t" | ||
352 | "mfhi\t%0" | ||
353 | : "=r" (res) | ||
354 | : "r" (count), "r" (quotient) | ||
355 | : "hi", "lo", GCC_REG_ACCUM); | ||
356 | |||
357 | /* | ||
358 | * Due to possible jiffies inconsistencies, we need to check | ||
359 | * the result so that we'll get a timer that is monotonic. | ||
360 | */ | ||
361 | if (res >= USECS_PER_JIFFY) | ||
362 | res = USECS_PER_JIFFY-1; | ||
363 | |||
364 | return res; | ||
365 | } | ||
366 | |||
367 | #ifdef CONFIG_PM | ||
368 | static unsigned long do_fast_pm_gettimeoffset(void) | ||
369 | { | ||
370 | unsigned long pc0; | ||
371 | unsigned long offset; | ||
372 | |||
373 | pc0 = au_readl(SYS_TOYREAD); | ||
374 | au_sync(); | ||
375 | offset = pc0 - last_pc0; | ||
376 | if (offset > 2*MATCH20_INC) { | ||
377 | printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", | ||
378 | (unsigned)offset, (unsigned)last_pc0, | ||
379 | (unsigned)last_match20, (unsigned)pc0); | ||
380 | } | ||
381 | offset = (unsigned long)((offset * 305) / 10); | ||
382 | return offset; | ||
383 | } | ||
384 | #endif | ||
385 | |||
386 | void __init plat_timer_setup(struct irqaction *irq) | 293 | void __init plat_timer_setup(struct irqaction *irq) |
387 | { | 294 | { |
388 | unsigned int est_freq; | 295 | unsigned int est_freq; |
@@ -420,7 +327,6 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
420 | unsigned int c0_status; | 327 | unsigned int c0_status; |
421 | 328 | ||
422 | printk("WARNING: no 32KHz clock found.\n"); | 329 | printk("WARNING: no 32KHz clock found.\n"); |
423 | do_gettimeoffset = do_fast_cp0_gettimeoffset; | ||
424 | 330 | ||
425 | /* Ensure we get CPO_COUNTER interrupts. | 331 | /* Ensure we get CPO_COUNTER interrupts. |
426 | */ | 332 | */ |
@@ -445,19 +351,11 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
445 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); | 351 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); |
446 | startup_match20_interrupt(counter0_irq); | 352 | startup_match20_interrupt(counter0_irq); |
447 | 353 | ||
448 | do_gettimeoffset = do_fast_pm_gettimeoffset; | ||
449 | |||
450 | /* We can use the real 'wait' instruction. | 354 | /* We can use the real 'wait' instruction. |
451 | */ | 355 | */ |
452 | allow_au1k_wait = 1; | 356 | allow_au1k_wait = 1; |
453 | } | 357 | } |
454 | 358 | ||
455 | #else | ||
456 | /* We have to do this here instead of in timer_init because | ||
457 | * the generic code in arch/mips/kernel/time.c will write | ||
458 | * over our function pointer. | ||
459 | */ | ||
460 | do_gettimeoffset = do_fast_cp0_gettimeoffset; | ||
461 | #endif | 359 | #endif |
462 | } | 360 | } |
463 | 361 | ||