Subversion Repositories shark

Rev

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