1 #include <linux/kernel.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>
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>
23 #include <linux/workqueue.h>
24 #include <linux/semaphore.h>
25 #include <linux/slab.h>
27 #include "mtkfb_vsync.h"
29 #include <linux/xlog.h>
31 #define VSYNC_DBG(...) xlog_printk(ANDROID_LOG_DEBUG, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
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__)
37 static size_t mtkfb_vsync_on
= false;
38 #define MTKFB_VSYNC_LOG(fmt, arg...) \
40 if (mtkfb_vsync_on) VSYNC_WRN(fmt, ##arg); \
43 #define MTKFB_VSYNC_FUNC() \
45 if(mtkfb_vsync_on) VSYNC_WRN("[Func]%s\n", __func__); \
48 static dev_t mtkfb_vsync_devno
;
49 static struct cdev
*mtkfb_vsync_cdev
;
50 static struct class *mtkfb_vsync_class
= NULL
;
52 DEFINE_SEMAPHORE(mtkfb_vsync_sem
);
54 extern void mtkfb_waitVsync(void);
55 extern void mtkfb_disable_non_fb_layer(void);
57 void mtkfb_vsync_log_enable(int enable
)
59 mtkfb_vsync_on
= enable
;
60 MTKFB_VSYNC_LOG("mtkfb_vsync log %s\n", enable
?"enabled":"disabled");
63 static int mtkfb_vsync_open(struct inode
*inode
, struct file
*file
)
65 VSYNC_DBG("driver open\n");
69 static ssize_t
mtkfb_vsync_read(struct file
*file
, char __user
*data
, size_t len
, loff_t
*ppos
)
71 VSYNC_DBG("driver read\n");
75 static int mtkfb_vsync_release(struct inode
*inode
, struct file
*file
)
77 VSYNC_DBG("driver release\n");
78 VSYNC_DBG("reset overlay engine\n");
79 //mtkfb_disable_non_fb_layer(); //[mo]
83 static int mtkfb_vsync_flush(struct file
* a_pstFile
, fl_owner_t a_id
)
85 // To Do : error handling here
89 static long mtkfb_vsync_unlocked_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
95 case MTKFB_VSYNC_IOCTL
:
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__
);
104 up(&mtkfb_vsync_sem
);
105 MTKFB_VSYNC_LOG("[MTKFB_VSYNC]: leave MTKFB_VSYNC_IOCTL\n");
113 static 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
,
122 static int mtkfb_vsync_probe(struct platform_device
*pdev
)
125 struct class_device
*class_dev
= NULL
;
127 pr_info("\n=== MTKFB_VSYNC probe ===\n");
129 if (alloc_chrdev_region(&mtkfb_vsync_devno
, 0, 1, MTKFB_VSYNC_DEVNAME
))
131 VSYNC_ERR("can't get device major number...\n");
135 pr_info("get device major number (%d)\n", mtkfb_vsync_devno
);
137 mtkfb_vsync_cdev
= cdev_alloc();
138 mtkfb_vsync_cdev
->owner
= THIS_MODULE
;
139 mtkfb_vsync_cdev
->ops
= &mtkfb_vsync_fops
;
141 cdev_add(mtkfb_vsync_cdev
, mtkfb_vsync_devno
, 1);
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
);
146 VSYNC_INF("probe is done\n");
150 static int mtkfb_vsync_remove(struct platform_device
*pdev
)
152 VSYNC_INF("device remove\n");
156 static void mtkfb_vsync_shutdown(struct platform_device
*pdev
)
158 pr_info("mtkfb_vsync device shutdown\n");
161 static int mtkfb_vsync_suspend(struct platform_device
*pdev
, pm_message_t mesg
)
166 static int mtkfb_vsync_resume(struct platform_device
*pdev
)
171 static 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
,
178 .name
= MTKFB_VSYNC_DEVNAME
,
182 static void mtkfb_vsync_device_release(struct device
*dev
)
186 static u64 mtkfb_vsync_dmamask
= ~(u32
)0;
188 static struct platform_device mtkfb_vsync_device
= {
189 .name
= MTKFB_VSYNC_DEVNAME
,
192 .release
= mtkfb_vsync_device_release
,
193 .dma_mask
= &mtkfb_vsync_dmamask
,
194 .coherent_dma_mask
= 0xffffffff,
199 static int __init
mtkfb_vsync_init(void)
201 VSYNC_INF("initializeing driver...\n");
203 if (platform_device_register(&mtkfb_vsync_device
))
205 VSYNC_ERR("failed to register device\n");
209 if (platform_driver_register(&mtkfb_vsync_driver
))
211 VSYNC_ERR("failed to register driver\n");
212 platform_device_unregister(&mtkfb_vsync_device
);
219 static void __exit
mtkfb_vsync_exit(void)
221 cdev_del(mtkfb_vsync_cdev
);
222 unregister_chrdev_region(mtkfb_vsync_devno
, 1);
224 platform_driver_unregister(&mtkfb_vsync_driver
);
225 platform_device_unregister(&mtkfb_vsync_device
);
227 device_destroy(mtkfb_vsync_class
, mtkfb_vsync_devno
);
228 class_destroy(mtkfb_vsync_class
);
230 VSYNC_INF("exit driver...\n");
233 module_init(mtkfb_vsync_init
);
234 module_exit(mtkfb_vsync_exit
);
236 MODULE_DESCRIPTION("MediaTek FB VSYNC Driver");
237 MODULE_AUTHOR("Zaikuo Wang <Zaikuo.Wang@mediatek.com>");