11 #include <linux/errno.h>
12 #include <linux/export.h>
13 #include <linux/sched.h>
14 #include <linux/kernel.h>
16 #include <linux/string.h>
19 #include <linux/time.h>
20 #include <linux/timex.h>
31 #include <linux/rtc.h>
40 #include <asm/oplib.h>
41 #include <asm/timer.h>
47 #include <asm/sections.h>
49 #include <asm/uaccess.h>
50 #include <asm/irq_regs.h>
56 #define TICK_PRIV_BIT (1UL << 63)
57 #define TICKCMP_IRQ_BIT (1UL << 63)
71 static void tick_disable_protection(
void)
81 "1: rd %%tick, %%g2\n"
82 " add %%g2, 6, %%g2\n"
83 " andn %%g2, %0, %%g2\n"
84 " wrpr %%g2, 0, %%tick\n"
91 static void tick_disable_irq(
void)
97 "1: wr %0, 0x0, %%tick_cmpr\n"
98 " rd %%tick_cmpr, %%g0"
103 static void tick_init_tick(
void)
105 tick_disable_protection();
109 static unsigned long long tick_get_tick(
void)
113 __asm__ __volatile__(
"rd %%tick, %0\n\t"
120 static int tick_add_compare(
unsigned long adj)
122 unsigned long orig_tick, new_tick, new_compare;
124 __asm__ __volatile__(
"rd %%tick, %0"
138 __asm__ __volatile__(
"ba,pt %%xcc, 1f\n\t"
139 " add %1, %2, %0\n\t"
142 "wr %0, 0, %%tick_cmpr\n\t"
143 "rd %%tick_cmpr, %%g0\n\t"
145 :
"r" (orig_tick),
"r" (adj));
147 __asm__ __volatile__(
"rd %%tick, %0"
151 return ((
long)(new_tick - (orig_tick+adj))) > 0
L;
154 static unsigned long tick_add_tick(
unsigned long adj)
156 unsigned long new_tick;
159 __asm__ __volatile__(
"rd %%tick, %0\n\t"
161 "wrpr %0, 0, %%tick\n\t"
170 .init_tick = tick_init_tick,
171 .disable_irq = tick_disable_irq,
172 .get_tick = tick_get_tick,
173 .add_tick = tick_add_tick,
174 .add_compare = tick_add_compare,
175 .softint_mask = 1
UL << 0,
181 static void stick_disable_irq(
void)
184 "wr %0, 0x0, %%asr25"
189 static void stick_init_tick(
void)
196 tick_disable_protection();
201 " rd %%asr24, %%g2\n"
202 " andn %%g2, %0, %%g2\n"
203 " wr %%g2, 0, %%asr24"
212 static unsigned long long stick_get_tick(
void)
216 __asm__ __volatile__(
"rd %%asr24, %0"
222 static unsigned long stick_add_tick(
unsigned long adj)
224 unsigned long new_tick;
226 __asm__ __volatile__(
"rd %%asr24, %0\n\t"
228 "wr %0, 0, %%asr24\n\t"
235 static int stick_add_compare(
unsigned long adj)
237 unsigned long orig_tick, new_tick;
239 __asm__ __volatile__(
"rd %%asr24, %0"
243 __asm__ __volatile__(
"wr %0, 0, %%asr25"
245 :
"r" (orig_tick + adj));
247 __asm__ __volatile__(
"rd %%asr24, %0"
251 return ((
long)(new_tick - (orig_tick+adj))) > 0
L;
256 .init_tick = stick_init_tick,
257 .disable_irq = stick_disable_irq,
258 .get_tick = stick_get_tick,
259 .add_tick = stick_add_tick,
260 .add_compare = stick_add_compare,
261 .softint_mask = 1
UL << 16,
281 #define HBIRD_STICKCMP_ADDR 0x1fe0000f060UL
282 #define HBIRD_STICK_ADDR 0x1fe0000f070UL
284 static unsigned long __hbird_read_stick(
void)
286 unsigned long ret,
tmp1, tmp2, tmp3;
289 __asm__ __volatile__(
"ldxa [%1] %5, %2\n"
291 "sub %1, 0x8, %1\n\t"
292 "ldxa [%1] %5, %3\n\t"
293 "add %1, 0x8, %1\n\t"
294 "ldxa [%1] %5, %4\n\t"
296 "bne,a,pn %%xcc, 1b\n\t"
298 "sllx %4, 32, %4\n\t"
300 :
"=&r" (ret),
"=&r" (addr),
301 "=&r" (tmp1),
"=&r" (tmp2),
"=&r" (tmp3)
307 static void __hbird_write_stick(
unsigned long val)
309 unsigned long low = (val & 0xffffffff
UL);
310 unsigned long high = (val >> 32
UL);
313 __asm__ __volatile__(
"stxa %%g0, [%0] %4\n\t"
314 "add %0, 0x8, %0\n\t"
315 "stxa %3, [%0] %4\n\t"
316 "sub %0, 0x8, %0\n\t"
319 :
"0" (addr),
"r" (low),
"r" (high),
323 static void __hbird_write_compare(
unsigned long val)
325 unsigned long low = (val & 0xffffffff
UL);
326 unsigned long high = (val >> 32
UL);
329 __asm__ __volatile__(
"stxa %3, [%0] %4\n\t"
330 "sub %0, 0x8, %0\n\t"
333 :
"0" (addr),
"r" (low),
"r" (high),
337 static void hbtick_disable_irq(
void)
342 static void hbtick_init_tick(
void)
344 tick_disable_protection();
351 __hbird_write_stick(__hbird_read_stick());
353 hbtick_disable_irq();
356 static unsigned long long hbtick_get_tick(
void)
361 static unsigned long hbtick_add_tick(
unsigned long adj)
365 val = __hbird_read_stick() + adj;
366 __hbird_write_stick(val);
371 static int hbtick_add_compare(
unsigned long adj)
373 unsigned long val = __hbird_read_stick();
378 __hbird_write_compare(val);
382 return ((
long)(val2 - val)) > 0
L;
387 .init_tick = hbtick_init_tick,
388 .disable_irq = hbtick_disable_irq,
389 .get_tick = hbtick_get_tick,
390 .add_tick = hbtick_add_tick,
391 .add_compare = hbtick_add_compare,
392 .softint_mask = 1UL << 0,
395 static unsigned long timer_ticks_per_nsec_quotient
__read_mostly;
413 static struct resource rtc_cmos_resource;
418 .resource = &rtc_cmos_resource,
427 op->
dev.of_node->full_name, op->
resource[0].start);
435 r = &rtc_cmos_resource;
448 .compatible =
"m5819",
452 .compatible =
"isa-m5819p",
456 .compatible =
"isa-m5823p",
460 .compatible =
"ds1287",
470 .of_match_table = rtc_match,
475 .name =
"rtc-bq4802",
484 op->
dev.of_node->full_name, op->
resource[0].start);
493 .compatible =
"bq4802",
499 .probe = bq4802_probe,
503 .of_match_table = bq4802_match,
507 static unsigned char mostek_read_byte(
struct device *
dev,
u32 ofs)
512 return readb(regs + ofs);
515 static void mostek_write_byte(
struct device *dev,
u32 ofs,
u8 val)
524 .read_byte = mostek_read_byte,
525 .write_byte = mostek_write_byte,
529 .name =
"rtc-m48t59",
533 .platform_data = &m48t59_data,
563 .probe = mostek_probe,
567 .of_match_table = mostek_match,
577 .name =
"rtc-starfire",
581 static int __init clock_init(
void)
603 static unsigned long sparc64_init_timers(
void)
610 unsigned long ver, manuf, impl;
612 __asm__ __volatile__ (
"rdpr %%ver, %0"
614 manuf = ((ver >> 48) & 0xffff);
615 impl = ((ver >> 32) & 0xffff);
616 if (manuf == 0x17 && impl == 0x13) {
648 #ifdef CONFIG_CPU_FREQ
650 static int sparc64_cpufreq_notifier(
struct notifier_block *nb,
unsigned long val,
654 unsigned int cpu = freq->
cpu;
677 static int __init register_sparc64_cpufreq_notifier(
void)
689 static int sparc64_next_event(
unsigned long delta,
690 struct clock_event_device *
evt)
695 static void sparc64_timer_setup(
enum clock_event_mode
mode,
696 struct clock_event_device *evt)
699 case CLOCK_EVT_MODE_ONESHOT:
700 case CLOCK_EVT_MODE_RESUME:
703 case CLOCK_EVT_MODE_SHUTDOWN:
707 case CLOCK_EVT_MODE_PERIODIC:
708 case CLOCK_EVT_MODE_UNUSED:
714 static struct clock_event_device sparc64_clockevent = {
715 .features = CLOCK_EVT_FEAT_ONESHOT,
716 .set_mode = sparc64_timer_setup,
717 .set_next_event = sparc64_next_event,
726 struct pt_regs *old_regs = set_irq_regs(regs);
727 unsigned long tick_mask =
tick_ops->softint_mask;
729 struct clock_event_device *evt = &
per_cpu(sparc64_events, cpu);
731 clear_softint(tick_mask);
738 if (
unlikely(!evt->event_handler)) {
740 "Spurious SPARC64 timer interrupt on cpu %d\n", cpu);
742 evt->event_handler(evt);
746 set_irq_regs(old_regs);
751 struct clock_event_device *sevt;
757 __asm__ __volatile__(
"rdpr %%pstate, %0\n\t"
758 "wrpr %0, %1, %%pstate"
765 __asm__ __volatile__(
"wrpr %0, 0x0, %%pstate"
771 memcpy(sevt, &sparc64_clockevent,
sizeof(*sevt));
777 #define SPARC64_NSEC_PER_CYC_SHIFT 10UL
789 unsigned long bclock, now;
794 }
while ((now-bclock) < loops);
811 unsigned long freq = sparc64_init_timers();
815 timer_ticks_per_nsec_quotient =
819 clocksource_tick.
read = clocksource_tick_read;
821 clocksource_register_hz(&clocksource_tick, freq);
822 printk(
"clocksource: mult[%x] shift[%d]\n",
823 clocksource_tick.
mult, clocksource_tick.
shift);
825 sparc64_clockevent.name =
tick_ops->name;
826 clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4);
828 sparc64_clockevent.max_delta_ns =
830 sparc64_clockevent.min_delta_ns =
833 printk(
"clockevent: mult[%x] shift[%d]\n",
834 sparc64_clockevent.mult, sparc64_clockevent.shift);
843 return (ticks * timer_ticks_per_nsec_quotient)