linux/drivers/cpufreq/unicore2-cpufreq.c
<<
>>
Prefs
   1/*
   2 * clock scaling for the UniCore-II
   3 *
   4 * Code specific to PKUnity SoC and UniCore ISA
   5 *
   6 *      Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
   7 *      Copyright (C) 2001-2010 Guan Xuetao
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/kernel.h>
  15#include <linux/types.h>
  16#include <linux/init.h>
  17#include <linux/clk.h>
  18#include <linux/cpufreq.h>
  19
  20#include <mach/hardware.h>
  21
  22static struct cpufreq_driver ucv2_driver;
  23
  24/* make sure that only the "userspace" governor is run
  25 * -- anything else wouldn't make sense on this platform, anyway.
  26 */
  27static int ucv2_verify_speed(struct cpufreq_policy *policy)
  28{
  29        if (policy->cpu)
  30                return -EINVAL;
  31
  32        cpufreq_verify_within_limits(policy,
  33                        policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
  34
  35        return 0;
  36}
  37
  38static unsigned int ucv2_getspeed(unsigned int cpu)
  39{
  40        struct clk *mclk = clk_get(NULL, "MAIN_CLK");
  41
  42        if (cpu)
  43                return 0;
  44        return clk_get_rate(mclk)/1000;
  45}
  46
  47static int ucv2_target(struct cpufreq_policy *policy,
  48                         unsigned int target_freq,
  49                         unsigned int relation)
  50{
  51        unsigned int cur = ucv2_getspeed(0);
  52        struct cpufreq_freqs freqs;
  53        struct clk *mclk = clk_get(NULL, "MAIN_CLK");
  54
  55        cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
  56
  57        if (!clk_set_rate(mclk, target_freq * 1000)) {
  58                freqs.old = cur;
  59                freqs.new = target_freq;
  60        }
  61
  62        cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
  63
  64        return 0;
  65}
  66
  67static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
  68{
  69        if (policy->cpu != 0)
  70                return -EINVAL;
  71        policy->cur = ucv2_getspeed(0);
  72        policy->min = policy->cpuinfo.min_freq = 250000;
  73        policy->max = policy->cpuinfo.max_freq = 1000000;
  74        policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
  75        return 0;
  76}
  77
  78static struct cpufreq_driver ucv2_driver = {
  79        .flags          = CPUFREQ_STICKY,
  80        .verify         = ucv2_verify_speed,
  81        .target         = ucv2_target,
  82        .get            = ucv2_getspeed,
  83        .init           = ucv2_cpu_init,
  84        .name           = "UniCore-II",
  85};
  86
  87static int __init ucv2_cpufreq_init(void)
  88{
  89        return cpufreq_register_driver(&ucv2_driver);
  90}
  91
  92arch_initcall(ucv2_cpufreq_init);
  93