Subversion Repositories shark

Rev

Rev 770 | 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
 
768 mauro 41
//extern void kern_scale_timer(unsigned int old_f, unsigned int new_f);
42
extern void ll_scale_advtimer(unsigned int old_f, unsigned int new_f);
770 mauro 43
extern ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf);
775 mauro 44
extern int get_available_freqs (struct cpufreq_policy *policy, int *buf);
582 mauro 45
/**
46
 * The "cpufreq driver" - the arch- or hardware-dependend low
47
 * level driver of CPUFreq support, and its spinlock. This lock
48
 * also protects the cpufreq_cpu_data array.
49
 */
597 mauro 50
static struct cpufreq_policy    cpufreq_cpu_policy;
51
static struct cpufreq_policy    *cpufreq_cpu_data = &cpufreq_cpu_policy;
582 mauro 52
static struct cpufreq_driver    *cpufreq_driver;
53
static spinlock_t               cpufreq_driver_lock = SPIN_LOCK_UNLOCKED;
54
 
55
/*********************************************************************
56
 *                                USER                               *
57
 *********************************************************************/
58
 
770 mauro 59
inline int cpufreq_target(unsigned int target_freq, unsigned int relation)
582 mauro 60
{
61
        return cpufreq_driver_target(cpufreq_cpu_data, target_freq, relation);
62
}
63
 
770 mauro 64
inline int cpufreq_get_cur_freq(void)
597 mauro 65
{
66
        return cpufreq_cpu_data->cur;
67
}
68
 
770 mauro 69
inline int cpufreq_get_min_freq(void)
597 mauro 70
{
71
        return cpufreq_cpu_data->min;
72
}
73
 
770 mauro 74
inline int cpufreq_get_max_freq(void)
597 mauro 75
{
76
        return cpufreq_cpu_data->max;
77
}
78
 
770 mauro 79
inline int cpufreq_get_latency(void)
597 mauro 80
{
81
        return cpufreq_cpu_data->cpuinfo.transition_latency;
82
}
83
 
775 mauro 84
inline int cpufreq_get_available_freqs(int *buf)
85
{
86
        return get_available_freqs(cpufreq_cpu_data, buf);
87
}
88
 
770 mauro 89
inline int cpufreq_show_available_freqs(char *buf)
90
{
91
        return show_available_freqs(cpufreq_cpu_data, buf);
92
}
93
 
582 mauro 94
/*********************************************************************
95
 *                              GOVERNOR                             *
96
 *********************************************************************/
97
 
98
int cpufreq_driver_target(struct cpufreq_policy *policy,
99
                          unsigned int target_freq,
100
                          unsigned int relation)
101
{
102
        unsigned int ret;
103
 
104
        if (!policy)
105
                return -EINVAL;
106
 
107
        ret = cpufreq_driver->target(policy, target_freq, relation);
108
 
109
        return ret;
110
}
111
 
112
/*********************************************************************
597 mauro 113
 *                              NOTIFIER                             *
114
 *********************************************************************/
115
void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
116
{
117
        switch (state) {
118
        case CPUFREQ_PRECHANGE:
119
                //adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
120
                break;
121
        case CPUFREQ_POSTCHANGE:
122
                //adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
768 mauro 123
                //kern_scale_timer(freqs->old, freqs->new);
124
                ll_scale_advtimer(freqs->old, freqs->new);
597 mauro 125
                cpufreq_cpu_data->cur = freqs->new;
126
                break;
127
        }
128
}
129
 
130
/*********************************************************************
582 mauro 131
 *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
132
 *********************************************************************/
133
 
134
/**
135
 * cpufreq_register_driver - register a CPU Frequency driver
136
 * @driver_data: A struct cpufreq_driver containing the values#
137
 * submitted by the CPU Frequency driver.
138
 *
139
 *   Registers a CPU Frequency driver to this core code. This code
140
 * returns zero on success, -EBUSY when another driver got here first
141
 * (and isn't unregistered in the meantime).
142
 *
143
 */
144
int cpufreq_register_driver(struct cpufreq_driver *driver_data)
145
{
146
        unsigned long flags;
147
 
148
        if (!driver_data || !driver_data->verify || !driver_data->init ||
149
            ((!driver_data->setpolicy) && (!driver_data->target)))
150
                return -EINVAL;
151
 
152
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
153
        if (cpufreq_driver) {
154
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
155
                return -EBUSY;
156
        }
157
        cpufreq_driver = driver_data;
158
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
159
 
160
        /* Init & verify - TODO */
161
        cpufreq_driver->init(cpufreq_cpu_data);
162
        cpufreq_driver->verify(cpufreq_cpu_data);
163
 
164
        return 0; //sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
165
}
166
 
167
/**
168
 * cpufreq_unregister_driver - unregister the current CPUFreq driver
169
 *
170
 *    Unregister the current CPUFreq driver. Only call this if you have
171
 * the right to do so, i.e. if you have succeeded in initialising before!
172
 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
173
 * currently not initialised.
174
 */
175
int cpufreq_unregister_driver(struct cpufreq_driver *driver)
176
{
177
        unsigned long flags;
178
 
179
        if (!cpufreq_driver || (driver != cpufreq_driver))
180
                return -EINVAL;
181
 
182
        /* Exit */
183
        cpufreq_driver->exit(cpufreq_cpu_data);
184
 
185
        //sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
186
 
187
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
188
        cpufreq_driver = NULL;
189
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
190
 
191
        return 0;
192
}