import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / video / mt8127 / mtkfb_vsync.c
CommitLineData
6fa3eb70
S
1#include <linux/kernel.h>
2#include <linux/mm.h>
3#include <linux/mm_types.h>
4#include <linux/module.h>
5#include <generated/autoconf.h>
6#include <linux/init.h>
7#include <linux/types.h>
8#include <linux/cdev.h>
9#include <linux/kdev_t.h>
10#include <linux/delay.h>
11#include <linux/ioport.h>
12#include <linux/platform_device.h>
13#include <linux/dma-mapping.h>
14#include <linux/device.h>
15#include <linux/fs.h>
16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/spinlock.h>
19#include <linux/param.h>
20#include <linux/uaccess.h>
21#include <linux/sched.h>
22
23#include <linux/workqueue.h>
24#include <linux/semaphore.h>
25#include <linux/slab.h>
26
27#include "mtkfb_vsync.h"
28
29#include <linux/xlog.h>
30
31#define VSYNC_DBG(...) xlog_printk(ANDROID_LOG_DEBUG, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
32
33#define VSYNC_INF(...) xlog_printk(ANDROID_LOG_INFO, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
34#define VSYNC_WRN(...) xlog_printk(ANDROID_LOG_WARN, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
35#define VSYNC_ERR(...) xlog_printk(ANDROID_LOG_ERROR, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
36
37static size_t mtkfb_vsync_on = false;
38#define MTKFB_VSYNC_LOG(fmt, arg...) \
39 do { \
40 if (mtkfb_vsync_on) VSYNC_WRN(fmt, ##arg); \
41 }while (0)
42
43#define MTKFB_VSYNC_FUNC() \
44 do { \
45 if(mtkfb_vsync_on) VSYNC_WRN("[Func]%s\n", __func__); \
46 }while (0)
47
48static dev_t mtkfb_vsync_devno;
49static struct cdev *mtkfb_vsync_cdev;
50static struct class *mtkfb_vsync_class = NULL;
51
52DEFINE_SEMAPHORE(mtkfb_vsync_sem);
53
54extern void mtkfb_waitVsync(void);
55extern void mtkfb_disable_non_fb_layer(void);
56
57void mtkfb_vsync_log_enable(int enable)
58{
59 mtkfb_vsync_on = enable;
60 MTKFB_VSYNC_LOG("mtkfb_vsync log %s\n", enable?"enabled":"disabled");
61}
62
63static int mtkfb_vsync_open(struct inode *inode, struct file *file)
64{
65 VSYNC_DBG("driver open\n");
66 return 0;
67}
68
69static ssize_t mtkfb_vsync_read(struct file *file, char __user *data, size_t len, loff_t *ppos)
70{
71 VSYNC_DBG("driver read\n");
72 return 0;
73}
74
75static int mtkfb_vsync_release(struct inode *inode, struct file *file)
76{
77 VSYNC_DBG("driver release\n");
78 VSYNC_DBG("reset overlay engine\n");
79 //mtkfb_disable_non_fb_layer(); //[mo]
80 return 0;
81}
82
83static int mtkfb_vsync_flush(struct file * a_pstFile , fl_owner_t a_id)
84{
85 // To Do : error handling here
86 return 0;
87}
88
89static long mtkfb_vsync_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
90{
91 int ret = 0;
92 MTKFB_VSYNC_FUNC();
93 switch (cmd)
94 {
95 case MTKFB_VSYNC_IOCTL:
96 {
97 MTKFB_VSYNC_LOG("[MTKFB_VSYNC]: enter MTKFB_VSYNC_IOCTL\n");
98 if (down_interruptible(&mtkfb_vsync_sem)) {
99 pr_info("[mtkfb_vsync_ioctl] can't get semaphore,%d\n", __LINE__);
100 msleep(20);
101 return ret;
102 }
103 mtkfb_waitVsync();
104 up(&mtkfb_vsync_sem);
105 MTKFB_VSYNC_LOG("[MTKFB_VSYNC]: leave MTKFB_VSYNC_IOCTL\n");
106 }
107 break;
108 }
109 return ret;
110}
111
112
113static struct file_operations mtkfb_vsync_fops = {
114 .owner = THIS_MODULE,
115 .unlocked_ioctl = mtkfb_vsync_unlocked_ioctl,
116 .open = mtkfb_vsync_open,
117 .release = mtkfb_vsync_release,
118 .flush = mtkfb_vsync_flush,
119 .read = mtkfb_vsync_read,
120};
121
122static int mtkfb_vsync_probe(struct platform_device *pdev)
123{
124 struct class_device;
125 struct class_device *class_dev = NULL;
126
127 pr_info("\n=== MTKFB_VSYNC probe ===\n");
128
129 if (alloc_chrdev_region(&mtkfb_vsync_devno, 0, 1, MTKFB_VSYNC_DEVNAME))
130 {
131 VSYNC_ERR("can't get device major number...\n");
132 return -EFAULT;
133 }
134
135 pr_info("get device major number (%d)\n", mtkfb_vsync_devno);
136
137 mtkfb_vsync_cdev = cdev_alloc();
138 mtkfb_vsync_cdev->owner = THIS_MODULE;
139 mtkfb_vsync_cdev->ops = &mtkfb_vsync_fops;
140
141 cdev_add(mtkfb_vsync_cdev, mtkfb_vsync_devno, 1);
142
143 mtkfb_vsync_class = class_create(THIS_MODULE, MTKFB_VSYNC_DEVNAME);
144 class_dev = (struct class_device *)device_create(mtkfb_vsync_class, NULL, mtkfb_vsync_devno, NULL, MTKFB_VSYNC_DEVNAME);
145
146 VSYNC_INF("probe is done\n");
147 return 0;
148}
149
150static int mtkfb_vsync_remove(struct platform_device *pdev)
151{
152 VSYNC_INF("device remove\n");
153 return 0;
154}
155
156static void mtkfb_vsync_shutdown(struct platform_device *pdev)
157{
158 pr_info("mtkfb_vsync device shutdown\n");
159}
160
161static int mtkfb_vsync_suspend(struct platform_device *pdev, pm_message_t mesg)
162{
163 return 0;
164}
165
166static int mtkfb_vsync_resume(struct platform_device *pdev)
167{
168 return 0;
169}
170
171static struct platform_driver mtkfb_vsync_driver = {
172 .probe = mtkfb_vsync_probe,
173 .remove = mtkfb_vsync_remove,
174 .shutdown = mtkfb_vsync_shutdown,
175 .suspend = mtkfb_vsync_suspend,
176 .resume = mtkfb_vsync_resume,
177 .driver = {
178 .name = MTKFB_VSYNC_DEVNAME,
179 },
180};
181
182static void mtkfb_vsync_device_release(struct device *dev)
183{
184}
185
186static u64 mtkfb_vsync_dmamask = ~(u32)0;
187
188static struct platform_device mtkfb_vsync_device = {
189 .name = MTKFB_VSYNC_DEVNAME,
190 .id = 0,
191 .dev = {
192 .release = mtkfb_vsync_device_release,
193 .dma_mask = &mtkfb_vsync_dmamask,
194 .coherent_dma_mask = 0xffffffff,
195 },
196 .num_resources = 0,
197};
198
199static int __init mtkfb_vsync_init(void)
200{
201 VSYNC_INF("initializeing driver...\n");
202
203 if (platform_device_register(&mtkfb_vsync_device))
204 {
205 VSYNC_ERR("failed to register device\n");
206 return -ENODEV;
207 }
208
209 if (platform_driver_register(&mtkfb_vsync_driver))
210 {
211 VSYNC_ERR("failed to register driver\n");
212 platform_device_unregister(&mtkfb_vsync_device);
213 return -ENODEV;
214 }
215
216 return 0;
217}
218
219static void __exit mtkfb_vsync_exit(void)
220{
221 cdev_del(mtkfb_vsync_cdev);
222 unregister_chrdev_region(mtkfb_vsync_devno, 1);
223
224 platform_driver_unregister(&mtkfb_vsync_driver);
225 platform_device_unregister(&mtkfb_vsync_device);
226
227 device_destroy(mtkfb_vsync_class, mtkfb_vsync_devno);
228 class_destroy(mtkfb_vsync_class);
229
230 VSYNC_INF("exit driver...\n");
231}
232
233module_init(mtkfb_vsync_init);
234module_exit(mtkfb_vsync_exit);
235
236MODULE_DESCRIPTION("MediaTek FB VSYNC Driver");
237MODULE_AUTHOR("Zaikuo Wang <Zaikuo.Wang@mediatek.com>");