| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- #include <linux/kernel.h>
- #include <linux/mm.h>
- #include <linux/mm_types.h>
- #include <linux/module.h>
- #include <generated/autoconf.h>
- #include <linux/init.h>
- #include <linux/types.h>
- #include <linux/cdev.h>
- #include <linux/kdev_t.h>
- #include <linux/delay.h>
- #include <linux/ioport.h>
- #include <linux/platform_device.h>
- #include <linux/dma-mapping.h>
- #include <linux/device.h>
- #include <linux/fs.h>
- #include <linux/interrupt.h>
- #include <linux/wait.h>
- #include <linux/spinlock.h>
- #include <linux/param.h>
- #include <linux/uaccess.h>
- #include <linux/sched.h>
- #include <linux/slab.h>
- #include <linux/xlog.h>
- #include <linux/io.h>
- #include "almk_drv.h"
- /* #define USE_SYSRAM */
- #define ALMK_MSG pr_debug
- #define ALMK_WRN pr_debug
- #define ALMK_ERR pr_err
- #define ALMK_DEVNAME "mtk_almk"
- #define ALMK_PROCESS 0x2
- /* -------------------------------------------------------------------------- */
- /* */
- /* -------------------------------------------------------------------------- */
- /* global function */
- static unsigned int _almk_int_status;
- /* device and driver */
- static dev_t almk_devno;
- static struct cdev *almk_cdev;
- static struct class *almk_class;
- /* static wait_queue_head_t enc_wait_queue; */
- static spinlock_t almk_lock;
- static int almk_status;
- #if 0
- static int check_all_minfree(void *param, void *param2)
- {
- #if 1
- struct task_struct *p = 0;
- int n = 4096 * 170000;
- int nr_pages = (n / PAGE_SIZE) + ((n % PAGE_SIZE) ? 1 : 0);
- int free_pages = global_page_state(NR_FREE_PAGES) +
- global_page_state(NR_FILE_PAGES) + global_page_state(NR_FILE_DIRTY);
- ALMK_MSG(KERN_ALERT "%s\n", __func__);
- ALMK_MSG(KERN_ALERT "=====================================\n");
- for_each_process(p) {
- /* get_min_free_pages(p->pid); */
- ALMK_MSG(KERN_ALERT "trying to alloc %d bytes (%d pages)\n"
- "(NR_FREE_PAGES) + (NR_FILE_PAGES) + (NR_FILE_DIRTY) - nr_pages = (%d + %d + %d - %d) = %d\n"
- "target_min_free_pages = %d\n",
- n, nr_pages,
- global_page_state(NR_FREE_PAGES),
- global_page_state(NR_FILE_PAGES),
- global_page_state(NR_FILE_DIRTY),
- nr_pages, free_pages - nr_pages, get_min_free_pages(p->pid));
- ALMK_MSG(KERN_ALERT "allocation is %s\n",
- (free_pages - nr_pages >= get_min_free_pages(p->pid)) ? "safe" : "not safe");
- }
- #endif
- }
- #endif
- static unsigned int get_max_safe_size(pid_t pid)
- {
- unsigned int all_free_pages;
- unsigned int lmk_pages;
- unsigned int lowBoundPages = get_min_free_pages(pid);
- unsigned int max_safe_size;
- lmk_pages = query_lmk_minfree(0);
- all_free_pages = global_page_state(NR_FREE_PAGES) +
- global_page_state(NR_FILE_PAGES) + global_page_state(NR_FILE_DIRTY);
- if (all_free_pages >= (lowBoundPages + lmk_pages))
- max_safe_size = (all_free_pages - lowBoundPages - lmk_pages) * PAGE_SIZE;
- else if (all_free_pages >= (lowBoundPages))
- max_safe_size = (all_free_pages - lowBoundPages) * PAGE_SIZE;
- else
- return 0;
- return max_safe_size;
- }
- static int almk_ioctl(unsigned int cmd, unsigned long arg, struct file *file)
- {
- ALMK_DRV_DATA drv_data;
- unsigned int max_safe_size;
- unsigned int *pStatus;
- pStatus = (unsigned int *)file->private_data;
- if (NULL == pStatus) {
- ALMK_WRN("Private data is null in flush operation. HOW COULD THIS HAPPEN ??\n");
- return -EFAULT;
- }
- switch (cmd) {
- /* initial and reset ALMK */
- case ALMK_IOCTL_CMD_INIT:
- ALMK_MSG("ALMK Driver Initial and Lock\n");
- *pStatus = ALMK_PROCESS;
- break;
- case ALMK_IOCTL_CMD_GET_MAX_SIZE:
- ALMK_MSG("ALMK Driver GET_MAX_SIZE!!\n");
- if (*pStatus != ALMK_PROCESS) {
- ALMK_WRN("Permission Denied! This process can not access ALMK Driver");
- return -EFAULT;
- }
- if (copy_from_user(&drv_data, (void *)arg, sizeof(ALMK_DRV_DATA))) {
- ALMK_WRN("ALMK Driver : Copy from user error\n");
- return -EFAULT;
- }
- max_safe_size = get_max_safe_size(drv_data.pid);
- if (copy_to_user(drv_data.maxSafeSize, &max_safe_size, sizeof(unsigned int))) {
- ALMK_WRN("ALMK Driver : Copy to user error (result)\n");
- return -EFAULT;
- }
- break;
- case ALMK_IOCTL_CMD_DEINIT:
- /* copy input parameters */
- ALMK_MSG("ALMK Driver Deinit!!\n");
- if (*pStatus != ALMK_PROCESS) {
- ALMK_WRN("Permission Denied! This process can not access ALMK Driver");
- return -EFAULT;
- }
- *pStatus = 0;
- return 0;
- }
- return 0;
- }
- /* -------------------------------------------------------------------------- */
- /* */
- /* -------------------------------------------------------------------------- */
- /* static int almk_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) */
- static long almk_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
- {
- switch (cmd) {
- case ALMK_IOCTL_CMD_INIT:
- case ALMK_IOCTL_CMD_GET_MAX_SIZE:
- case ALMK_IOCTL_CMD_DEINIT:
- return almk_ioctl(cmd, arg, file);
- default:
- break;
- }
- return -EINVAL;
- }
- static int almk_open(struct inode *inode, struct file *file)
- {
- unsigned int *pStatus;
- /* Allocate and initialize private data */
- file->private_data = kmalloc(sizeof(unsigned int), GFP_ATOMIC);
- if (NULL == file->private_data) {
- ALMK_WRN("Not enough entry for ALMK open operation\n");
- return -ENOMEM;
- }
- pStatus = (unsigned int *)file->private_data;
- *pStatus = 0;
- return 0;
- }
- static ssize_t almk_read(struct file *file, char __user *data, size_t len, loff_t *ppos)
- {
- ALMK_MSG("almk driver read\n");
- return 0;
- }
- static int almk_release(struct inode *inode, struct file *file)
- {
- if (NULL != file->private_data) {
- kfree(file->private_data);
- file->private_data = NULL;
- }
- return 0;
- }
- static int almk_flush(struct file *a_pstFile, fl_owner_t a_id)
- {
- unsigned int *pStatus;
- pStatus = (unsigned int *)a_pstFile->private_data;
- if (NULL == pStatus) {
- ALMK_WRN("Private data is null in flush operation. HOW COULD THIS HAPPEN ??\n");
- return -EFAULT;
- }
- return 0;
- }
- /* Kernel interface */
- static struct file_operations const almk_fops = {
- .owner = THIS_MODULE,
- /* .ioctl = almk_ioctl, */
- .unlocked_ioctl = almk_unlocked_ioctl,
- .open = almk_open,
- .release = almk_release,
- .flush = almk_flush,
- .read = almk_read,
- };
- static int almk_probe(struct platform_device *pdev)
- {
- struct class_device;
- int ret;
- struct class_device *class_dev = NULL;
- ALMK_MSG("-------------almk driver probe-------\n");
- ret = alloc_chrdev_region(&almk_devno, 0, 1, ALMK_DEVNAME);
- if (ret)
- ALMK_ERR("Error: Can't Get Major number for ALMK Device\n");
- else
- ALMK_MSG("Get ALMK Device Major number (%d)\n", almk_devno);
- almk_cdev = cdev_alloc();
- almk_cdev->owner = THIS_MODULE;
- almk_cdev->ops = &almk_fops;
- ret = cdev_add(almk_cdev, almk_devno, 1);
- almk_class = class_create(THIS_MODULE, ALMK_DEVNAME);
- class_dev =
- (struct class_device *)device_create(almk_class, NULL, almk_devno, NULL, ALMK_DEVNAME);
- spin_lock_init(&almk_lock);
- /* initial driver, register driver ISR */
- almk_status = 0;
- _almk_int_status = 0;
- ALMK_MSG("ALMK Probe Done\n");
- /* NOT_REFERENCED(class_dev); */
- return 0;
- }
- static int almk_remove(struct platform_device *pdev)
- {
- ALMK_MSG("ALMK driver remove\n");
- ALMK_MSG("Done\n");
- return 0;
- }
- static void almk_shutdown(struct platform_device *pdev)
- {
- ALMK_MSG("ALMK driver shutdown\n");
- /* Nothing yet */
- }
- /* PM suspend */
- static int almk_suspend(struct platform_device *pdev, pm_message_t mesg)
- {
- /* almk_drv_dec_deinit(); */
- /* almk_drv_enc_deinit(); */
- return 0;
- }
- /* PM resume */
- static int almk_resume(struct platform_device *pdev)
- {
- return 0;
- }
- static struct platform_driver almk_driver = {
- .probe = almk_probe,
- .remove = almk_remove,
- .shutdown = almk_shutdown,
- .suspend = almk_suspend,
- .resume = almk_resume,
- .driver = {
- .name = ALMK_DEVNAME,
- },
- };
- static void almk_device_release(struct device *dev)
- {
- /* Nothing to release? */
- }
- static u64 jpegdec_dmamask = ~(u32) 0;
- static struct platform_device almk_device = {
- .name = ALMK_DEVNAME,
- .id = 0,
- .dev = {
- .release = almk_device_release,
- .dma_mask = &jpegdec_dmamask,
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = 0,
- };
- static int __init almk_init(void)
- {
- int ret;
- ALMK_MSG("ALMK driver initialize\n");
- ALMK_MSG("Register the ALMK driver device\n");
- if (platform_device_register(&almk_device)) {
- ALMK_ERR("failed to register jpeg driver device\n");
- ret = -ENODEV;
- return ret;
- }
- ALMK_MSG("Register the ALMK driver\n");
- if (platform_driver_register(&almk_driver)) {
- ALMK_ERR("failed to register jpeg driver\n");
- platform_device_unregister(&almk_device);
- ret = -ENODEV;
- return ret;
- }
- return 0;
- }
- static void __exit almk_exit(void)
- {
- cdev_del(almk_cdev);
- unregister_chrdev_region(almk_devno, 1);
- platform_driver_unregister(&almk_driver);
- platform_device_unregister(&almk_device);
- device_destroy(almk_class, almk_devno);
- class_destroy(almk_class);
- ALMK_MSG("Done\n");
- }
- module_init(almk_init);
- module_exit(almk_exit);
- MODULE_AUTHOR("Otis, Huang <otis.huang@mediatek.com>");
- MODULE_DESCRIPTION("ALMK driver");
- MODULE_LICENSE("GPL");
|