Subversion Repositories shark

Rev

Rev 597 | Rev 768 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
582 mauro 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Mauro Marinoni      <mauro.marinoni@unipv.it>
10
 *
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/*
20
 *  This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
21
 *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne P�k�� Dominik Brodowski.
22
 *
23
 *  Licensed under the terms of the GNU GPL License version 2.
24
 *
25
 *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
26
 */
27
 
28
#include <linuxcomp.h>
29
 
30
#include <linux/config.h>
31
#include <linux/kernel.h>
32
#include <linux/module.h>
33
#include <linux/init.h>
34
#include <linux/cpufreq.h>
35
#include <linux/delay.h>
36
#include <linux/interrupt.h>
37
#include <linux/spinlock.h>
38
#include <linux/slab.h>
39
#include <linux/cpu.h>
40
 
647 mauro 41
extern void kern_scale_timer(unsigned int old_f, unsigned int new_f);
42
 
582 mauro 43
/**
44
 * The "cpufreq driver" - the arch- or hardware-dependend low
45
 * level driver of CPUFreq support, and its spinlock. This lock
46
 * also protects the cpufreq_cpu_data array.
47
 */
597 mauro 48
static struct cpufreq_policy    cpufreq_cpu_policy;
49
static struct cpufreq_policy    *cpufreq_cpu_data = &cpufreq_cpu_policy;
582 mauro 50
static struct cpufreq_driver    *cpufreq_driver;
51
static spinlock_t               cpufreq_driver_lock = SPIN_LOCK_UNLOCKED;
52
 
53
/*********************************************************************
54
 *                                USER                               *
55
 *********************************************************************/
56
 
57
int cpufreq_target(unsigned int target_freq, unsigned int relation)
58
{
59
        return cpufreq_driver_target(cpufreq_cpu_data, target_freq, relation);
60
}
61
 
597 mauro 62
int cpufreq_get_cur_freq(void)
63
{
64
        return cpufreq_cpu_data->cur;
65
}
66
 
67
int cpufreq_get_min_freq(void)
68
{
69
        return cpufreq_cpu_data->min;
70
}
71
 
72
int cpufreq_get_max_freq(void)
73
{
74
        return cpufreq_cpu_data->max;
75
}
76
 
77
int cpufreq_get_latency(void)
78
{
79
        return cpufreq_cpu_data->cpuinfo.transition_latency;
80
}
81
 
582 mauro 82
/*********************************************************************
83
 *                              GOVERNOR                             *
84
 *********************************************************************/
85
 
86
int cpufreq_driver_target(struct cpufreq_policy *policy,
87
                          unsigned int target_freq,
88
                          unsigned int relation)
89
{
90
        unsigned int ret;
91
 
92
        if (!policy)
93
                return -EINVAL;
94
 
95
        ret = cpufreq_driver->target(policy, target_freq, relation);
96
 
97
        return ret;
98
}
99
 
100
/*********************************************************************
597 mauro 101
 *                              NOTIFIER                             *
102
 *********************************************************************/
103
void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
104
{
105
        switch (state) {
106
        case CPUFREQ_PRECHANGE:
107
                //adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
108
                break;
109
        case CPUFREQ_POSTCHANGE:
110
                //adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
647 mauro 111
                kern_scale_timer(freqs->old, freqs->new);
597 mauro 112
                cpufreq_cpu_data->cur = freqs->new;
113
                break;
114
        }
115
}
116
 
117
/*********************************************************************
582 mauro 118
 *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
119
 *********************************************************************/
120
 
121
/**
122
 * cpufreq_register_driver - register a CPU Frequency driver
123
 * @driver_data: A struct cpufreq_driver containing the values#
124
 * submitted by the CPU Frequency driver.
125
 *
126
 *   Registers a CPU Frequency driver to this core code. This code
127
 * returns zero on success, -EBUSY when another driver got here first
128
 * (and isn't unregistered in the meantime).
129
 *
130
 */
131
int cpufreq_register_driver(struct cpufreq_driver *driver_data)
132
{
133
        unsigned long flags;
134
 
135
        if (!driver_data || !driver_data->verify || !driver_data->init ||
136
            ((!driver_data->setpolicy) && (!driver_data->target)))
137
                return -EINVAL;
138
 
139
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
140
        if (cpufreq_driver) {
141
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
142
                return -EBUSY;
143
        }
144
        cpufreq_driver = driver_data;
145
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
146
 
147
        /* Init & verify - TODO */
148
        cpufreq_driver->init(cpufreq_cpu_data);
149
        cpufreq_driver->verify(cpufreq_cpu_data);
150
 
151
        return 0; //sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
152
}
153
 
154
/**
155
 * cpufreq_unregister_driver - unregister the current CPUFreq driver
156
 *
157
 *    Unregister the current CPUFreq driver. Only call this if you have
158
 * the right to do so, i.e. if you have succeeded in initialising before!
159
 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
160
 * currently not initialised.
161
 */
162
int cpufreq_unregister_driver(struct cpufreq_driver *driver)
163
{
164
        unsigned long flags;
165
 
166
        if (!cpufreq_driver || (driver != cpufreq_driver))
167
                return -EINVAL;
168
 
169
        /* Exit */
170
        cpufreq_driver->exit(cpufreq_cpu_data);
171
 
172
        //sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
173
 
174
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
175
        cpufreq_driver = NULL;
176
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
177
 
178
        return 0;
179
}