diff options
-rw-r--r-- | arch/mips/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/mips/philips/pnx8550/common/time.c | 44 |
2 files changed, 37 insertions, 9 deletions
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 11aab6d6bfe5..8aa544f73a5e 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
@@ -94,10 +94,8 @@ static void c0_timer_ack(void) | |||
94 | { | 94 | { |
95 | unsigned int count; | 95 | unsigned int count; |
96 | 96 | ||
97 | #ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */ | ||
98 | /* Ack this timer interrupt and set the next one. */ | 97 | /* Ack this timer interrupt and set the next one. */ |
99 | expirelo += cycles_per_jiffy; | 98 | expirelo += cycles_per_jiffy; |
100 | #endif | ||
101 | write_c0_compare(expirelo); | 99 | write_c0_compare(expirelo); |
102 | 100 | ||
103 | /* Check to see if we have missed any timer interrupts. */ | 101 | /* Check to see if we have missed any timer interrupts. */ |
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c index 65c440e8480b..f80acae07cee 100644 --- a/arch/mips/philips/pnx8550/common/time.c +++ b/arch/mips/philips/pnx8550/common/time.c | |||
@@ -33,7 +33,17 @@ | |||
33 | #include <int.h> | 33 | #include <int.h> |
34 | #include <cm.h> | 34 | #include <cm.h> |
35 | 35 | ||
36 | extern unsigned int mips_hpt_frequency; | 36 | static unsigned long cpj; |
37 | |||
38 | static cycle_t hpt_read(void) | ||
39 | { | ||
40 | return read_c0_count2(); | ||
41 | } | ||
42 | |||
43 | static void timer_ack(void) | ||
44 | { | ||
45 | write_c0_compare(cpj); | ||
46 | } | ||
37 | 47 | ||
38 | /* | 48 | /* |
39 | * pnx8550_time_init() - it does the following things: | 49 | * pnx8550_time_init() - it does the following things: |
@@ -68,27 +78,47 @@ void pnx8550_time_init(void) | |||
68 | * HZ timer interrupts per second. | 78 | * HZ timer interrupts per second. |
69 | */ | 79 | */ |
70 | mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p)); | 80 | mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p)); |
81 | cpj = (mips_hpt_frequency + HZ / 2) / HZ; | ||
82 | timer_ack(); | ||
83 | |||
84 | /* Setup Timer 2 */ | ||
85 | write_c0_count2(0); | ||
86 | write_c0_compare2(0xffffffff); | ||
87 | |||
88 | clocksource_mips.read = hpt_read; | ||
89 | mips_timer_ack = timer_ack; | ||
90 | } | ||
91 | |||
92 | static irqreturn_t monotonic_interrupt(int irq, void *dev_id) | ||
93 | { | ||
94 | /* Timer 2 clear interrupt */ | ||
95 | write_c0_compare2(-1); | ||
96 | return IRQ_HANDLED; | ||
71 | } | 97 | } |
72 | 98 | ||
99 | static struct irqaction monotonic_irqaction = { | ||
100 | .handler = monotonic_interrupt, | ||
101 | .flags = IRQF_DISABLED, | ||
102 | .name = "Monotonic timer", | ||
103 | }; | ||
104 | |||
73 | void __init plat_timer_setup(struct irqaction *irq) | 105 | void __init plat_timer_setup(struct irqaction *irq) |
74 | { | 106 | { |
75 | int configPR; | 107 | int configPR; |
76 | 108 | ||
77 | setup_irq(PNX8550_INT_TIMER1, irq); | 109 | setup_irq(PNX8550_INT_TIMER1, irq); |
110 | setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction); | ||
78 | 111 | ||
79 | /* Start timer1 */ | 112 | /* Timer 1 start */ |
80 | configPR = read_c0_config7(); | 113 | configPR = read_c0_config7(); |
81 | configPR &= ~0x00000008; | 114 | configPR &= ~0x00000008; |
82 | write_c0_config7(configPR); | 115 | write_c0_config7(configPR); |
83 | 116 | ||
84 | /* Timer 2 stop */ | 117 | /* Timer 2 start */ |
85 | configPR = read_c0_config7(); | 118 | configPR = read_c0_config7(); |
86 | configPR |= 0x00000010; | 119 | configPR &= ~0x00000010; |
87 | write_c0_config7(configPR); | 120 | write_c0_config7(configPR); |
88 | 121 | ||
89 | write_c0_count2(0); | ||
90 | write_c0_compare2(0xffffffff); | ||
91 | |||
92 | /* Timer 3 stop */ | 122 | /* Timer 3 stop */ |
93 | configPR = read_c0_config7(); | 123 | configPR = read_c0_config7(); |
94 | configPR |= 0x00000020; | 124 | configPR |= 0x00000020; |