0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/bug.h>
0010 #include <linux/clockchips.h>
0011 #include <linux/types.h>
0012 #include <linux/kernel.h>
0013 #include <linux/init.h>
0014 #include <linux/sched.h>
0015 #include <linux/param.h>
0016 #include <linux/time.h>
0017 #include <linux/timex.h>
0018 #include <linux/smp.h>
0019 #include <linux/spinlock.h>
0020 #include <linux/export.h>
0021 #include <linux/cpufreq.h>
0022 #include <linux/delay.h>
0023
0024 #include <asm/cpu-features.h>
0025 #include <asm/cpu-type.h>
0026 #include <asm/div64.h>
0027 #include <asm/time.h>
0028
0029 #ifdef CONFIG_CPU_FREQ
0030
0031 static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref);
0032 static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref_freq);
0033 static unsigned long glb_lpj_ref;
0034 static unsigned long glb_lpj_ref_freq;
0035
0036 static int cpufreq_callback(struct notifier_block *nb,
0037 unsigned long val, void *data)
0038 {
0039 struct cpufreq_freqs *freq = data;
0040 struct cpumask *cpus = freq->policy->cpus;
0041 unsigned long lpj;
0042 int cpu;
0043
0044
0045
0046
0047
0048 if (freq->flags & CPUFREQ_CONST_LOOPS)
0049 return NOTIFY_OK;
0050
0051
0052 if (!glb_lpj_ref) {
0053 glb_lpj_ref = boot_cpu_data.udelay_val;
0054 glb_lpj_ref_freq = freq->old;
0055
0056 for_each_online_cpu(cpu) {
0057 per_cpu(pcp_lpj_ref, cpu) =
0058 cpu_data[cpu].udelay_val;
0059 per_cpu(pcp_lpj_ref_freq, cpu) = freq->old;
0060 }
0061 }
0062
0063
0064
0065
0066
0067 if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
0068 (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
0069 loops_per_jiffy = cpufreq_scale(glb_lpj_ref,
0070 glb_lpj_ref_freq,
0071 freq->new);
0072
0073 for_each_cpu(cpu, cpus) {
0074 lpj = cpufreq_scale(per_cpu(pcp_lpj_ref, cpu),
0075 per_cpu(pcp_lpj_ref_freq, cpu),
0076 freq->new);
0077 cpu_data[cpu].udelay_val = (unsigned int)lpj;
0078 }
0079 }
0080
0081 return NOTIFY_OK;
0082 }
0083
0084 static struct notifier_block cpufreq_notifier = {
0085 .notifier_call = cpufreq_callback,
0086 };
0087
0088 static int __init register_cpufreq_notifier(void)
0089 {
0090 return cpufreq_register_notifier(&cpufreq_notifier,
0091 CPUFREQ_TRANSITION_NOTIFIER);
0092 }
0093 core_initcall(register_cpufreq_notifier);
0094
0095 #endif
0096
0097
0098
0099
0100 DEFINE_SPINLOCK(rtc_lock);
0101 EXPORT_SYMBOL(rtc_lock);
0102
0103 static int null_perf_irq(void)
0104 {
0105 return 0;
0106 }
0107
0108 int (*perf_irq)(void) = null_perf_irq;
0109
0110 EXPORT_SYMBOL(perf_irq);
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 unsigned int mips_hpt_frequency;
0124 EXPORT_SYMBOL_GPL(mips_hpt_frequency);
0125
0126 static __init int cpu_has_mfc0_count_bug(void)
0127 {
0128 switch (current_cpu_type()) {
0129 case CPU_R4000PC:
0130 case CPU_R4000SC:
0131 case CPU_R4000MC:
0132
0133
0134
0135
0136
0137 return 1;
0138
0139 case CPU_R4400PC:
0140 case CPU_R4400SC:
0141 case CPU_R4400MC:
0142
0143
0144
0145
0146
0147 return 1;
0148 }
0149
0150 return 0;
0151 }
0152
0153 void __init time_init(void)
0154 {
0155 plat_time_init();
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 if (mips_clockevent_init() != 0 || !cpu_has_mfc0_count_bug())
0166 init_mips_clocksource();
0167 }