Blame view

arch/arm/common/time-acorn.c 2.05 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /*
   *  linux/arch/arm/common/time-acorn.c
   *
   *  Copyright (c) 1996-2000 Russell King.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   *  Changelog:
   *   24-Sep-1996	RMK	Created
   *   10-Oct-1996	RMK	Brought up to date with arch-sa110eval
   *   04-Dec-1997	RMK	Updated for new arch/arm/time.c
   *   13=Jun-2004	DS	Moved to arch/arm/common b/c shared w/CLPS7500
   */
  #include <linux/timex.h>
  #include <linux/init.h>
  #include <linux/interrupt.h>
c4bfa28ae   Thomas Gleixner   [ARM] 3686/1: ARM...
19
  #include <linux/irq.h>
fced80c73   Russell King   [ARM] Convert asm...
20
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21

a09e64fbc   Russell King   [ARM] Move includ...
22
  #include <mach/hardware.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  #include <asm/hardware/ioc.h>
  
  #include <asm/mach/time.h>
  
  unsigned long ioc_timer_gettimeoffset(void)
  {
  	unsigned int count1, count2, status;
  	long offset;
  
  	ioc_writeb (0, IOC_T0LATCH);
  	barrier ();
  	count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
  	barrier ();
  	status = ioc_readb(IOC_IRQREQA);
  	barrier ();
  	ioc_writeb (0, IOC_T0LATCH);
  	barrier ();
  	count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
  
  	offset = count2;
  	if (count2 < count1) {
  		/*
  		 * We have not had an interrupt between reading count1
  		 * and count2.
  		 */
  		if (status & (1 << 5))
  			offset -= LATCH;
  	} else if (count2 > count1) {
  		/*
  		 * We have just had another interrupt between reading
  		 * count1 and count2.
  		 */
  		offset -= LATCH;
  	}
  
  	offset = (LATCH - offset) * (tick_nsec / 1000);
  	return (offset + LATCH/2) / LATCH;
  }
  
  void __init ioctime_init(void)
  {
  	ioc_writeb(LATCH & 255, IOC_T0LTCHL);
  	ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
  	ioc_writeb(0, IOC_T0GO);
  }
  
  static irqreturn_t
0cd61b68c   Linus Torvalds   Initial blind fix...
70
  ioc_timer_interrupt(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  {
0cd61b68c   Linus Torvalds   Initial blind fix...
72
  	timer_tick();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
75
76
77
  	return IRQ_HANDLED;
  }
  
  static struct irqaction ioc_timer_irq = {
  	.name		= "timer",
52e405eaa   Thomas Gleixner   [PATCH] ARM: fixu...
78
  	.flags		= IRQF_DISABLED,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  	.handler	= ioc_timer_interrupt
  };
  
  /*
   * Set up timer interrupt.
   */
  static void __init ioc_timer_init(void)
  {
  	ioctime_init();
  	setup_irq(IRQ_TIMER, &ioc_timer_irq);
  }
  
  struct sys_timer ioc_timer = {
  	.init		= ioc_timer_init,
  	.offset		= ioc_timer_gettimeoffset,
  };