Subversion Repositories shark

Rev

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