--- a/libutil/op_cpufreq.c
+++ b/libutil/op_cpufreq.c
@@ -2,11 +2,12 @@
  * @file op_cpufreq.c
  * get cpu frequency definition
  *
- * @remark Copyright 2003 OProfile authors
+ * @remark Copyright 2011 OProfile authors
  * @remark Read the file COPYING
  *
  * @author John Levon
  * @author Philippe Elie
+ * @author Suravee Suthikulpanit
  */
 
 #include <stdio.h>
@@ -14,7 +15,13 @@
 
 #include "op_fileio.h"
 
-double op_cpu_frequency(void)
+/*
+ * Use frequency information from /proc/cpuinfo. This should be available in most case.
+ * However, this number is the current cpu frequency which could be in the idle state.
+ * We should actually report the max frequency because the cpu should switch into the
+ * highest power state when running.
+ */
+static double op_cpu_freq_cpuinfo(void)
 {
 	double fval = 0.0;
 	unsigned long uval;
@@ -67,3 +74,60 @@
 
 	return fval;
 }
+
+
+/*
+ * Use frequency information from /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
+ * This number is the maximum cpu frequency of the processor.
+ */
+static double op_cpu_freq_sys_devices(void)
+{
+	double fval = 0.0;
+	char * line = NULL;
+
+	FILE * fp = op_try_open_file("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
+	if (!fp)
+		return 0.0;
+
+	while (1) {
+		line = op_get_line(fp);
+
+		if (!line)
+			break;
+
+		if (line[0] == '\0') {
+			free(line);
+			continue;
+		}
+
+		if (sscanf(line, "%lf", &fval) == 1)
+			break;
+
+		free(line);
+	}
+
+	if (line)
+		free(line);
+	op_close_file(fp);
+
+	return fval;
+}
+
+
+double op_cpu_frequency(void)
+{
+	/*
+	 * Typically, system changes the frequency scaling of the cpus
+	 * based on the workload.  /proc/cpuinfo reports the current
+	 * frequency value which might not be at the maximum at the time
+	 * of query.  Since cpu switch into running state with max frequency
+	 * when under workload, we should make sure to report the max frequency
+	 * value acquiring from /sys/devices when available.
+	 */
+
+	double freq = op_cpu_freq_sys_devices();
+	if (freq == 0) {
+		freq = op_cpu_freq_cpuinfo();
+	}
+	return freq;
+}