OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [misc/] [hdpuftrs/] [hdpu_cpustate.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *      Sky CPU State Driver
3
 *
4
 *      Copyright (C) 2002 Brian Waite
5
 *
6
 *      This driver allows use of the CPU state bits
7
 *      It exports the /dev/sky_cpustate and also
8
 *      /proc/sky_cpustate pseudo-file for status information.
9
 *
10
 *      This program is free software; you can redistribute it and/or
11
 *      modify it under the terms of the GNU General Public License
12
 *      as published by the Free Software Foundation; either version
13
 *      2 of the License, or (at your option) any later version.
14
 *
15
 */
16
 
17
#include <linux/module.h>
18
#include <linux/kernel.h>
19
#include <linux/spinlock.h>
20
#include <linux/miscdevice.h>
21
#include <linux/proc_fs.h>
22
#include <linux/hdpu_features.h>
23
#include <linux/platform_device.h>
24
#include <asm/uaccess.h>
25
#include <linux/seq_file.h>
26
#include <asm/io.h>
27
 
28
#define SKY_CPUSTATE_VERSION            "1.1"
29
 
30
static int hdpu_cpustate_probe(struct platform_device *pdev);
31
static int hdpu_cpustate_remove(struct platform_device *pdev);
32
 
33
static unsigned char cpustate_get_state(void);
34
static int cpustate_proc_open(struct inode *inode, struct file *file);
35
static int cpustate_proc_read(struct seq_file *seq, void *offset);
36
 
37
static struct cpustate_t cpustate;
38
 
39
static const struct file_operations proc_cpustate = {
40
        .open = cpustate_proc_open,
41
        .read = seq_read,
42
        .llseek = seq_lseek,
43
        .release = single_release,
44
        .owner = THIS_MODULE,
45
};
46
 
47
static int cpustate_proc_open(struct inode *inode, struct file *file)
48
{
49
        return single_open(file, cpustate_proc_read, NULL);
50
}
51
 
52
static int cpustate_proc_read(struct seq_file *seq, void *offset)
53
{
54
        seq_printf(seq, "CPU State: %04x\n", cpustate_get_state());
55
        return 0;
56
}
57
 
58
static int cpustate_get_ref(int excl)
59
{
60
 
61
        int retval = -EBUSY;
62
 
63
        spin_lock(&cpustate.lock);
64
 
65
        if (cpustate.excl)
66
                goto out_busy;
67
 
68
        if (excl) {
69
                if (cpustate.open_count)
70
                        goto out_busy;
71
                cpustate.excl = 1;
72
        }
73
 
74
        cpustate.open_count++;
75
        retval = 0;
76
 
77
      out_busy:
78
        spin_unlock(&cpustate.lock);
79
        return retval;
80
}
81
 
82
static int cpustate_free_ref(void)
83
{
84
 
85
        spin_lock(&cpustate.lock);
86
 
87
        cpustate.excl = 0;
88
        cpustate.open_count--;
89
 
90
        spin_unlock(&cpustate.lock);
91
        return 0;
92
}
93
 
94
static unsigned char cpustate_get_state(void)
95
{
96
 
97
        return cpustate.cached_val;
98
}
99
 
100
static void cpustate_set_state(unsigned char new_state)
101
{
102
        unsigned int state = (new_state << 21);
103
 
104
#ifdef DEBUG_CPUSTATE
105
        printk("CPUSTATE -> 0x%x\n", new_state);
106
#endif
107
        spin_lock(&cpustate.lock);
108
        cpustate.cached_val = new_state;
109
        writel((0xff << 21), cpustate.clr_addr);
110
        writel(state, cpustate.set_addr);
111
        spin_unlock(&cpustate.lock);
112
}
113
 
114
/*
115
 *      Now all the various file operations that we export.
116
 */
117
 
118
static ssize_t cpustate_read(struct file *file, char *buf,
119
                             size_t count, loff_t * ppos)
120
{
121
        unsigned char data;
122
 
123
        if (count < 0)
124
                return -EFAULT;
125
        if (count == 0)
126
                return 0;
127
 
128
        data = cpustate_get_state();
129
        if (copy_to_user(buf, &data, sizeof(unsigned char)))
130
                return -EFAULT;
131
        return sizeof(unsigned char);
132
}
133
 
134
static ssize_t cpustate_write(struct file *file, const char *buf,
135
                              size_t count, loff_t * ppos)
136
{
137
        unsigned char data;
138
 
139
        if (count < 0)
140
                return -EFAULT;
141
 
142
        if (count == 0)
143
                return 0;
144
 
145
        if (copy_from_user((unsigned char *)&data, buf, sizeof(unsigned char)))
146
                return -EFAULT;
147
 
148
        cpustate_set_state(data);
149
        return sizeof(unsigned char);
150
}
151
 
152
static int cpustate_open(struct inode *inode, struct file *file)
153
{
154
        return cpustate_get_ref((file->f_flags & O_EXCL));
155
}
156
 
157
static int cpustate_release(struct inode *inode, struct file *file)
158
{
159
        return cpustate_free_ref();
160
}
161
 
162
static struct platform_driver hdpu_cpustate_driver = {
163
        .probe = hdpu_cpustate_probe,
164
        .remove = hdpu_cpustate_remove,
165
        .driver = {
166
                .name = HDPU_CPUSTATE_NAME,
167
        },
168
};
169
 
170
/*
171
 *      The various file operations we support.
172
 */
173
static const struct file_operations cpustate_fops = {
174
      .owner    = THIS_MODULE,
175
      .open     = cpustate_open,
176
      .release  = cpustate_release,
177
      .read     = cpustate_read,
178
      .write    = cpustate_write,
179
      .llseek   = no_llseek,
180
};
181
 
182
static struct miscdevice cpustate_dev = {
183
        .minor  = MISC_DYNAMIC_MINOR,
184
        .name   = "sky_cpustate",
185
        .fops   = &cpustate_fops,
186
};
187
 
188
static int hdpu_cpustate_probe(struct platform_device *pdev)
189
{
190
        struct resource *res;
191
        struct proc_dir_entry *proc_de;
192
        int ret;
193
 
194
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
195
        if (!res) {
196
                printk(KERN_ERR "sky_cpustate: "
197
                       "Invalid memory resource.\n");
198
                return -EINVAL;
199
        }
200
        cpustate.set_addr = (unsigned long *)res->start;
201
        cpustate.clr_addr = (unsigned long *)res->end - 1;
202
 
203
        ret = misc_register(&cpustate_dev);
204
        if (ret) {
205
                printk(KERN_WARNING "sky_cpustate: "
206
                       "Unable to register misc device.\n");
207
                cpustate.set_addr = NULL;
208
                cpustate.clr_addr = NULL;
209
                return ret;
210
        }
211
 
212
        proc_de = create_proc_entry("sky_cpustate", 0666, &proc_root);
213
        if (!proc_de) {
214
                printk(KERN_WARNING "sky_cpustate: "
215
                       "Unable to create proc entry\n");
216
        } else {
217
                proc_de->proc_fops = &proc_cpustate;
218
                proc_de->owner = THIS_MODULE;
219
        }
220
 
221
        printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n");
222
        return 0;
223
}
224
 
225
static int hdpu_cpustate_remove(struct platform_device *pdev)
226
{
227
        cpustate.set_addr = NULL;
228
        cpustate.clr_addr = NULL;
229
 
230
        remove_proc_entry("sky_cpustate", NULL);
231
        misc_deregister(&cpustate_dev);
232
 
233
        return 0;
234
}
235
 
236
static int __init cpustate_init(void)
237
{
238
        return platform_driver_register(&hdpu_cpustate_driver);
239
}
240
 
241
static void __exit cpustate_exit(void)
242
{
243
        platform_driver_unregister(&hdpu_cpustate_driver);
244
}
245
 
246
module_init(cpustate_init);
247
module_exit(cpustate_exit);
248
 
249
MODULE_AUTHOR("Brian Waite");
250
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.