2018-05-14 17:33:46 +03:00
/*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
# include <linux/module.h>
# include <drm/drm_gem.h>
# include <drm/drm_crtc_helper.h>
2018-05-16 20:55:36 -03:00
# include <drm/drm_atomic_helper.h>
2018-05-14 17:33:46 +03:00
# include "vkms_drv.h"
# define DRIVER_NAME "vkms"
# define DRIVER_DESC "Virtual Kernel Mode Setting"
# define DRIVER_DATE "20180514"
# define DRIVER_MAJOR 1
# define DRIVER_MINOR 0
2018-05-16 20:55:36 -03:00
# define XRES_MIN 32
# define YRES_MIN 32
# define XRES_MAX 8192
# define YRES_MAX 8192
2018-05-14 17:33:46 +03:00
static struct vkms_device * vkms_device ;
static const struct file_operations vkms_driver_fops = {
. owner = THIS_MODULE ,
. open = drm_open ,
. mmap = drm_gem_mmap ,
. unlocked_ioctl = drm_ioctl ,
. compat_ioctl = drm_compat_ioctl ,
. poll = drm_poll ,
. read = drm_read ,
. llseek = no_llseek ,
. release = drm_release ,
} ;
static void vkms_release ( struct drm_device * dev )
{
struct vkms_device * vkms = container_of ( dev , struct vkms_device , drm ) ;
platform_device_unregister ( vkms - > platform ) ;
drm_mode_config_cleanup ( & vkms - > drm ) ;
drm_dev_fini ( & vkms - > drm ) ;
}
2018-05-15 19:30:52 +08:00
static struct drm_driver vkms_driver = {
2018-05-14 17:33:46 +03:00
. driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM ,
. release = vkms_release ,
. fops = & vkms_driver_fops ,
. name = DRIVER_NAME ,
. desc = DRIVER_DESC ,
. date = DRIVER_DATE ,
. major = DRIVER_MAJOR ,
. minor = DRIVER_MINOR ,
} ;
2018-05-16 20:56:21 -03:00
static const struct drm_mode_config_funcs vkms_mode_funcs = {
. atomic_check = drm_atomic_helper_check ,
. atomic_commit = drm_atomic_helper_commit ,
2018-05-14 17:33:46 +03:00
} ;
2018-05-16 20:56:21 -03:00
static int vkms_modeset_init ( struct vkms_device * vkmsdev )
2018-05-14 17:33:46 +03:00
{
2018-05-16 20:56:21 -03:00
struct drm_device * dev = & vkmsdev - > drm ;
2018-05-14 17:33:46 +03:00
2018-05-16 20:56:21 -03:00
drm_mode_config_init ( dev ) ;
dev - > mode_config . funcs = & vkms_mode_funcs ;
dev - > mode_config . min_width = XRES_MIN ;
dev - > mode_config . min_height = YRES_MIN ;
dev - > mode_config . max_width = XRES_MAX ;
dev - > mode_config . max_height = YRES_MAX ;
2018-05-14 17:33:46 +03:00
2018-05-16 20:56:21 -03:00
return vkms_output_init ( vkmsdev ) ;
}
2018-05-16 20:55:36 -03:00
2018-05-14 17:33:46 +03:00
static int __init vkms_init ( void )
{
int ret ;
vkms_device = kzalloc ( sizeof ( * vkms_device ) , GFP_KERNEL ) ;
if ( ! vkms_device )
return - ENOMEM ;
ret = drm_dev_init ( & vkms_device - > drm , & vkms_driver , NULL ) ;
if ( ret )
goto out_free ;
vkms_device - > platform =
platform_device_register_simple ( DRIVER_NAME , - 1 , NULL , 0 ) ;
if ( IS_ERR ( vkms_device - > platform ) ) {
ret = PTR_ERR ( vkms_device - > platform ) ;
goto out_fini ;
}
2018-05-16 20:56:21 -03:00
ret = vkms_modeset_init ( vkms_device ) ;
if ( ret )
2018-05-14 17:33:46 +03:00
goto out_unregister ;
ret = drm_dev_register ( & vkms_device - > drm , 0 ) ;
if ( ret )
goto out_unregister ;
return 0 ;
out_unregister :
platform_device_unregister ( vkms_device - > platform ) ;
2018-05-16 20:56:21 -03:00
2018-05-14 17:33:46 +03:00
out_fini :
drm_dev_fini ( & vkms_device - > drm ) ;
2018-05-16 20:56:21 -03:00
2018-05-14 17:33:46 +03:00
out_free :
kfree ( vkms_device ) ;
return ret ;
}
static void __exit vkms_exit ( void )
{
if ( ! vkms_device ) {
DRM_INFO ( " vkms_device is NULL. \n " ) ;
return ;
}
drm_dev_unregister ( & vkms_device - > drm ) ;
drm_dev_put ( & vkms_device - > drm ) ;
kfree ( vkms_device ) ;
}
module_init ( vkms_init ) ;
module_exit ( vkms_exit ) ;
2018-05-16 20:56:40 -03:00
MODULE_AUTHOR ( " Haneen Mohammed <hamohammed.sa@gmail.com> " ) ;
MODULE_AUTHOR ( " Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com> " ) ;
2018-05-14 17:33:46 +03:00
MODULE_DESCRIPTION ( DRIVER_DESC ) ;
MODULE_LICENSE ( " GPL " ) ;