diff options
Diffstat (limited to 'drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c')
-rw-r--r-- | drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c | 206 |
1 files changed, 126 insertions, 80 deletions
diff --git a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c index 28339699f7d5..8af59c77b381 100644 --- a/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c +++ b/drivers/mxc/amd-gpu/platform/hal/linux/gsl_kmod.c @@ -15,7 +15,7 @@ * 02110-1301, USA. * */ - + #include "gsl_types.h" #include "gsl.h" #include "gsl_buildconfig.h" @@ -34,12 +34,10 @@ #include <asm/uaccess.h> #include <linux/mm.h> #include <linux/mutex.h> -#include <linux/platform_device.h>
-#include <linux/vmalloc.h>
+#include <linux/cdev.h> -static int gsl_kmod_major; // TODO: move to gsl_kmod_data -static struct vm_operations_struct gsl_kmod_vmops = {0}; -DEFINE_MUTEX(gsl_mutex); // TODO: move to gsl_kmod_data? +#include <linux/platform_device.h> +#include <linux/vmalloc.h> static int gpu_2d_irq, gpu_3d_irq; @@ -51,27 +49,133 @@ int gmem_size; phys_addr_t gpu_reserved_mem; int gpu_reserved_mem_size; -/* structure to hold kernel module specific data. */ -struct gsl_kmod_data +static ssize_t gsl_kmod_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr); +static ssize_t gsl_kmod_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr); +static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd, unsigned long arg); +static int gsl_kmod_mmap(struct file *fd, struct vm_area_struct *vma); +static int gsl_kmod_fault(struct vm_area_struct *vma, struct vm_fault *vmf); +static int gsl_kmod_open(struct inode *inode, struct file *fd); +static int gsl_kmod_release(struct inode *inode, struct file *fd); +static irqreturn_t z160_irq_handler(int irq, void *dev_id); +#if defined(MX51) +static irqreturn_t z430_irq_handler(int irq, void *dev_id); +#endif + +static int gsl_kmod_major; +static struct class *gsl_kmod_class; +DEFINE_MUTEX(gsl_mutex); + +static const struct file_operations gsl_kmod_fops = +{ + .owner = THIS_MODULE, + .read = gsl_kmod_read, + .write = gsl_kmod_write, + .ioctl = gsl_kmod_ioctl, + .mmap = gsl_kmod_mmap, + .open = gsl_kmod_open, + .release = gsl_kmod_release +}; + +static struct vm_operations_struct gsl_kmod_vmops = { -// unsigned int major; - struct device *device; - /* stores the current open file descriptor during user process calls. - * It's a hack but in Linux the upper level driver cannot track processes - * as they are unique in Linux and not represent thread group as in WinCE. - */ - struct file *current_fd; + .fault = gsl_kmod_fault, }; -static struct gsl_kmod_data gsl_kmod_data = {0}; +static int __init gsl_kmod_init(void) +{ + struct device *dev; + + if (kgsl_driver_init() != GSL_SUCCESS) + { + printk(KERN_ERR "%s: kgsl_driver_init error\n", __func__); + goto kgsl_driver_init_error; + } + +#if defined(MX51) + if (request_irq(MX51_YDX_INTERRUPT, z430_irq_handler, 0, "ydx", NULL) < 0) + { + printk(KERN_ERR "%s: request_irq error\n", __func__); + goto request_irq_error; + } +#endif + +#if defined(MX51) + if (request_irq(MX51_G12_INTERRUPT, z160_irq_handler, 0, "g12", NULL) < 0) +#elif defined(MX35) + if (request_irq(MX35_G12_INTERRUPT, z160_irq_handler, 0, "g12", NULL) < 0) +#endif + { + printk(KERN_ERR "%s: request_irq error\n", __func__); + goto request_irq_error; + } + + gsl_kmod_major = register_chrdev(0, "gsl_kmod", &gsl_kmod_fops); + gsl_kmod_vmops.fault = gsl_kmod_fault; + + if (gsl_kmod_major <= 0) + { + pr_err("%s: register_chrdev error\n", __func__); + goto register_chrdev_error; + } + + gsl_kmod_class = class_create(THIS_MODULE, "gsl_kmod"); + + if (IS_ERR(gsl_kmod_class)) + { + pr_err("%s: class_create error\n", __func__); + goto class_create_error; + } + + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) + dev = device_create(gsl_kmod_class, NULL, MKDEV(gsl_kmod_major, 0), "gsl_kmod"); + #else + dev = device_create(gsl_kmod_class, NULL, MKDEV(gsl_kmod_major, 0), NULL,"gsl_kmod"); + #endif + + if (!IS_ERR(dev)) + { + return 0; + } + + pr_err("%s: device_create error\n", __func__); + +class_create_error: + class_destroy(gsl_kmod_class); + +register_chrdev_error: + unregister_chrdev(gsl_kmod_major, "gsl_kmod"); -static unsigned int current_fd; +request_irq_error: +kgsl_driver_init_error: + kgsl_driver_close(); + return 0; // TODO: return proper error code +} -unsigned int get_current_fd(void) +static void __exit gsl_kmod_exit(void) { - return current_fd; + device_destroy(gsl_kmod_class, MKDEV(gsl_kmod_major, 0)); + class_destroy(gsl_kmod_class); + unregister_chrdev(gsl_kmod_major, "gsl_kmod"); +#if defined(MX51) + free_irq(MX51_YDX_INTERRUPT, NULL); + free_irq(MX51_G12_INTERRUPT, NULL); +#elif defined(MX35) + free_irq(MX35_G12_INTERRUPT, NULL); +#endif + kgsl_driver_close(); } +module_init(gsl_kmod_init); +module_exit(gsl_kmod_exit); + +MODULE_AUTHOR("Advanced Micro Devices"); +#if defined(MX51) +MODULE_DESCRIPTION("AMD 2D/3D graphics core driver for i.MX51"); +#elif defined(MX35) +MODULE_DESCRIPTION("AMD 2D graphics core driver for i.MX35"); +#endif +MODULE_LICENSE("GPL v2"); + static ssize_t gsl_kmod_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) { return 0; @@ -86,12 +190,6 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd { int kgslStatus = GSL_FAILURE; - if(mutex_lock_interruptible(&gsl_mutex)) - { - return -EINTR; - } - current_fd = (unsigned int)fd; - switch (cmd) { case IOCTL_KGSL_DEVICE_START: { @@ -502,7 +600,7 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd { printk(KERN_ERR "%s: kgsl_sharedmem_write failed\n", __func__); } - + break; } case IOCTL_KGSL_SHAREDMEM_SET: @@ -603,6 +701,7 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd kgslStatus = GSL_SUCCESS; break; } + case IOCTL_KGSL_DEVICE_CLOCK: { kgsl_device_clock_t param; @@ -620,10 +719,6 @@ static int gsl_kmod_ioctl(struct inode *inode, struct file *fd, unsigned int cmd break; } - current_fd = 0; - - mutex_unlock(&gsl_mutex); - return kgslStatus; } @@ -639,13 +734,6 @@ static int gsl_kmod_mmap(struct file *fd, struct vm_area_struct *vma) void *va; #endif - if(mutex_lock_interruptible(&gsl_mutex)) - { - return -EINTR; - } - - current_fd = (unsigned int)fd; - #ifdef GSL_MMU_TRANSLATION_ENABLED if (addr < GSL_LINUX_MAP_RANGE_END && addr >= GSL_LINUX_MAP_RANGE_START) { @@ -654,8 +742,6 @@ static int gsl_kmod_mmap(struct file *fd, struct vm_area_struct *vma) { if (remap_pfn_range(vma, start, vmalloc_to_pfn(va), PAGE_SIZE, prot)) { - current_fd = 0; - mutex_unlock(&gsl_mutex); return -EAGAIN; } start += PAGE_SIZE; @@ -674,16 +760,9 @@ static int gsl_kmod_mmap(struct file *fd, struct vm_area_struct *vma) vma->vm_ops = &gsl_kmod_vmops; - current_fd = 0; - - mutex_unlock(&gsl_mutex); - return status; } -/* we install fault handler here to signal bus error if user tries to access - * outside of VMA. - */ static int gsl_kmod_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { return VM_FAULT_SIGBUS; @@ -700,8 +779,6 @@ static int gsl_kmod_open(struct inode *inode, struct file *fd) return -EINTR; } - current_fd = (unsigned int)fd; - if (kgsl_driver_entry(flags) != GSL_SUCCESS) { printk(KERN_INFO "%s: kgsl_driver_entry error\n", __func__); @@ -726,8 +803,6 @@ static int gsl_kmod_open(struct inode *inode, struct file *fd) } } - current_fd = 0; - mutex_unlock(&gsl_mutex); return err; @@ -743,8 +818,6 @@ static int gsl_kmod_release(struct inode *inode, struct file *fd) return -EINTR; } - current_fd = (unsigned int)fd; - /* make sure contexts are destroyed */ del_all_devices_contexts(fd); @@ -762,8 +835,6 @@ static int gsl_kmod_release(struct inode *inode, struct file *fd) fd->private_data = 0; } - current_fd = 0; - mutex_unlock(&gsl_mutex); return err; @@ -771,17 +842,6 @@ static int gsl_kmod_release(struct inode *inode, struct file *fd) static struct class *gsl_kmod_class; -static const struct file_operations gsl_kmod_fops = -{ - .owner = THIS_MODULE, - .read = gsl_kmod_read, - .write = gsl_kmod_write, - .ioctl = gsl_kmod_ioctl, - .mmap = gsl_kmod_mmap, - .open = gsl_kmod_open, - .release = gsl_kmod_release -}; - static irqreturn_t z160_irq_handler(int irq, void *dev_id) { kgsl_intr_isr(); @@ -891,7 +951,7 @@ static int gpu_probe(struct platform_device *pdev) if (!IS_ERR(dev)) { - gsl_kmod_data.device = dev; + // gsl_kmod_data.device = dev; return 0; } @@ -987,20 +1047,6 @@ static struct platform_driver gpu_driver = { .resume = gpu_resume, }; -static int __init gsl_kmod_init(void) -{ - int ret = platform_driver_register(&gpu_driver); - - return ret; -} - -static void __exit gsl_kmod_exit(void) -{ - platform_driver_unregister(&gpu_driver); -} - -module_init(gsl_kmod_init); -module_exit(gsl_kmod_exit); MODULE_AUTHOR("Advanced Micro Devices Inc."); #if defined(MX51) |