Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[pandora-kernel.git] / drivers / staging / msm / mdp4_debugfs.c
1 /* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/time.h>
21 #include <linux/init.h>
22 #include <linux/interrupt.h>
23 #include <linux/spinlock.h>
24 #include <linux/hrtimer.h>
25 #include <linux/clk.h>
26 #include <mach/hardware.h>
27 #include <linux/io.h>
28 #include <linux/debugfs.h>
29
30 #include <asm/system.h>
31 #include <asm/mach-types.h>
32 #include <linux/semaphore.h>
33 #include <linux/uaccess.h>
34
35 #include "mdp.h"
36 #include "msm_fb.h"
37 #include "mdp4.h"
38
39
40 #define MDP4_DEBUG_BUF  128
41
42
43 static char mdp4_debug_buf[MDP4_DEBUG_BUF];
44 static ulong mdp4_debug_offset;
45 static ulong mdp4_base_addr;
46
47 static int mdp4_offset_set(void *data, u64 val)
48 {
49         mdp4_debug_offset = (int)val;
50         return 0;
51 }
52
53 static int mdp4_offset_get(void *data, u64 *val)
54 {
55         *val = (u64)mdp4_debug_offset;
56         return 0;
57 }
58
59 DEFINE_SIMPLE_ATTRIBUTE(
60                         mdp4_offset_fops,
61                         mdp4_offset_get,
62                         mdp4_offset_set,
63                         "%llx\n");
64
65
66 static int mdp4_debugfs_open(struct inode *inode, struct file *file)
67 {
68         /* non-seekable */
69         file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
70         return 0;
71 }
72
73 static int mdp4_debugfs_release(struct inode *inode, struct file *file)
74 {
75         return 0;
76 }
77
78 static ssize_t mdp4_debugfs_write(
79         struct file *file,
80         const char __user *buff,
81         size_t count,
82         loff_t *ppos)
83 {
84         int cnt;
85         unsigned int data;
86
87         printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n",
88                 __func__, (int)mdp4_debug_offset, (int)count, (int)*ppos);
89
90         if (count > sizeof(mdp4_debug_buf))
91                 return -EFAULT;
92
93         if (copy_from_user(mdp4_debug_buf, buff, count))
94                 return -EFAULT;
95
96
97         mdp4_debug_buf[count] = 0;      /* end of string */
98
99         cnt = sscanf(mdp4_debug_buf, "%x", &data);
100         if (cnt < 1) {
101                 printk(KERN_ERR "%s: sscanf failed cnt=%d" , __func__, cnt);
102                 return -EINVAL;
103         }
104
105         writel(&data, mdp4_base_addr + mdp4_debug_offset);
106
107         return 0;
108 }
109
110 static ssize_t mdp4_debugfs_read(
111         struct file *file,
112         char __user *buff,
113         size_t count,
114         loff_t *ppos)
115 {
116         int len = 0;
117         unsigned int data;
118
119         printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n",
120                 __func__, (int)mdp4_debug_offset, (int)count, (int)*ppos);
121
122         if (*ppos)
123                 return 0;       /* the end */
124
125         data = readl(mdp4_base_addr + mdp4_debug_offset);
126
127         len = snprintf(mdp4_debug_buf, 4, "%x\n", data);
128
129         if (len > 0) {
130                 if (len > count)
131                         len = count;
132                 if (copy_to_user(buff, mdp4_debug_buf, len))
133                         return -EFAULT;
134         }
135
136         printk(KERN_INFO "%s: len=%d\n", __func__, len);
137
138         if (len < 0)
139                 return 0;
140
141         *ppos += len;   /* increase offset */
142
143         return len;
144 }
145
146 static const struct file_operations mdp4_debugfs_fops = {
147         .open = mdp4_debugfs_open,
148         .release = mdp4_debugfs_release,
149         .read = mdp4_debugfs_read,
150         .write = mdp4_debugfs_write,
151 };
152
153 int mdp4_debugfs_init(void)
154 {
155         struct dentry *dent = debugfs_create_dir("mdp4", NULL);
156
157         if (IS_ERR(dent)) {
158                 printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
159                         __FILE__, __LINE__, PTR_ERR(dent));
160                 return -1;
161         }
162
163         if (debugfs_create_file("offset", 0644, dent, 0, &mdp4_offset_fops)
164                         == NULL) {
165                 printk(KERN_ERR "%s(%d): debugfs_create_file: offset fail\n",
166                         __FILE__, __LINE__);
167                 return -1;
168         }
169
170         if (debugfs_create_file("regs", 0644, dent, 0, &mdp4_debugfs_fops)
171                         == NULL) {
172                 printk(KERN_ERR "%s(%d): debugfs_create_file: regs fail\n",
173                         __FILE__, __LINE__);
174                 return -1;
175         }
176
177         mdp4_debug_offset = 0;
178         mdp4_base_addr = (ulong) msm_mdp_base;  /* defined at msm_fb_def.h */
179
180         return 0;
181 }