diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-10-19 03:22:38 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-10-19 13:15:58 -0400 |
commit | d527eef5b7f151320921f0ff7a88297cefc5be72 (patch) | |
tree | 8376bc3dd03818f8274a16753605cba84eee0653 /arch/mips/sibyte/bcm1480/time.c | |
parent | 93c846f9047f392fc2335668a5234edfbddb7cdc (diff) |
[MIPS] Sibyte: Finish conversion to modern time APIs.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/sibyte/bcm1480/time.c')
-rw-r--r-- | arch/mips/sibyte/bcm1480/time.c | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index 5b4bfbbb5a24..c730744aa474 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c | |||
@@ -27,9 +27,8 @@ | |||
27 | */ | 27 | */ |
28 | #include <linux/clockchips.h> | 28 | #include <linux/clockchips.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/sched.h> | 30 | #include <linux/percpu.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/kernel_stat.h> | ||
33 | 32 | ||
34 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
35 | #include <asm/addrspace.h> | 34 | #include <asm/addrspace.h> |
@@ -101,25 +100,36 @@ static void sibyte_set_mode(enum clock_event_mode mode, | |||
101 | break; | 100 | break; |
102 | 101 | ||
103 | case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ | 102 | case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ |
103 | case CLOCK_EVT_MODE_RESUME: | ||
104 | ; | 104 | ; |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | struct clock_event_device sibyte_hpt_clockevent = { | 108 | static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) |
109 | .name = "bcm1480-counter", | 109 | { |
110 | .features = CLOCK_EVT_FEAT_PERIODIC, | 110 | unsigned int cpu = smp_processor_id(); |
111 | .set_mode = sibyte_set_mode, | 111 | void __iomem *timer_init; |
112 | .shift = 32, | 112 | unsigned int cnt; |
113 | .irq = 0, | 113 | int res; |
114 | }; | 114 | |
115 | timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); | ||
116 | cnt = __raw_readq(timer_init); | ||
117 | cnt += delta; | ||
118 | __raw_writeq(cnt, timer_init); | ||
119 | res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0; | ||
120 | |||
121 | return res; | ||
122 | } | ||
123 | |||
124 | static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent); | ||
115 | 125 | ||
116 | static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) | 126 | static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) |
117 | { | 127 | { |
118 | struct clock_event_device *cd = &sibyte_hpt_clockevent; | ||
119 | unsigned int cpu = smp_processor_id(); | 128 | unsigned int cpu = smp_processor_id(); |
129 | struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); | ||
120 | 130 | ||
121 | /* Reset the timer */ | 131 | /* Reset the timer */ |
122 | __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, | 132 | __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, |
123 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | 133 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); |
124 | cd->event_handler(cd); | 134 | cd->event_handler(cd); |
125 | 135 | ||
@@ -140,24 +150,21 @@ static struct irqaction sibyte_counter_irqaction = { | |||
140 | * called directly from irq_handler.S when IP[4] is set during an | 150 | * called directly from irq_handler.S when IP[4] is set during an |
141 | * interrupt | 151 | * interrupt |
142 | */ | 152 | */ |
143 | static void __init sb1480_clockevent_init(void) | 153 | void __cpuinit sb1480_clockevent_init(void) |
144 | { | 154 | { |
145 | unsigned int cpu = smp_processor_id(); | 155 | unsigned int cpu = smp_processor_id(); |
146 | unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; | 156 | unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; |
157 | struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); | ||
147 | 158 | ||
148 | setup_irq(irq, &sibyte_counter_irqaction); | 159 | cd->name = "bcm1480-counter"; |
149 | } | 160 | cd->features = CLOCK_EVT_FEAT_PERIODIC | |
161 | CLOCK_EVT_MODE_ONESHOT; | ||
162 | cd->set_next_event = sibyte_next_event; | ||
163 | cd->set_mode = sibyte_set_mode; | ||
164 | cd->irq = irq; | ||
165 | clockevent_set_clock(cd, BCM1480_HPT_VALUE); | ||
150 | 166 | ||
151 | void bcm1480_timer_interrupt(void) | 167 | setup_irq(irq, &sibyte_counter_irqaction); |
152 | { | ||
153 | int cpu = smp_processor_id(); | ||
154 | int irq = K_BCM1480_INT_TIMER_0 + cpu; | ||
155 | |||
156 | /* Reset the timer */ | ||
157 | __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, | ||
158 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | ||
159 | |||
160 | ll_timer_interrupt(irq); | ||
161 | } | 168 | } |
162 | 169 | ||
163 | static cycle_t bcm1480_hpt_read(void) | 170 | static cycle_t bcm1480_hpt_read(void) |
@@ -168,9 +175,26 @@ static cycle_t bcm1480_hpt_read(void) | |||
168 | return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; | 175 | return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; |
169 | } | 176 | } |
170 | 177 | ||
178 | struct clocksource bcm1480_clocksource = { | ||
179 | .name = "MIPS", | ||
180 | .rating = 200, | ||
181 | .read = bcm1480_hpt_read, | ||
182 | .mask = CLOCKSOURCE_MASK(32), | ||
183 | .shift = 32, | ||
184 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
185 | }; | ||
186 | |||
187 | void __init sb1480_clocksource_init(void) | ||
188 | { | ||
189 | struct clocksource *cs = &bcm1480_clocksource; | ||
190 | |||
191 | clocksource_set_clock(cs, BCM1480_HPT_VALUE); | ||
192 | clocksource_register(cs); | ||
193 | } | ||
194 | |||
171 | void __init bcm1480_hpt_setup(void) | 195 | void __init bcm1480_hpt_setup(void) |
172 | { | 196 | { |
173 | clocksource_mips.read = bcm1480_hpt_read; | ||
174 | mips_hpt_frequency = BCM1480_HPT_VALUE; | 197 | mips_hpt_frequency = BCM1480_HPT_VALUE; |
198 | sb1480_clocksource_init(); | ||
175 | sb1480_clockevent_init(); | 199 | sb1480_clockevent_init(); |
176 | } | 200 | } |