0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <linux/err.h>
0029 #include <linux/init.h>
0030 #include <linux/kernel.h>
0031 #include <linux/mm.h>
0032 #include <linux/platform_data/simplefb.h>
0033 #include <linux/platform_device.h>
0034 #include <linux/screen_info.h>
0035 #include <linux/sysfb.h>
0036
0037 static struct platform_device *pd;
0038 static DEFINE_MUTEX(disable_lock);
0039 static bool disabled;
0040
0041 static bool sysfb_unregister(void)
0042 {
0043 if (IS_ERR_OR_NULL(pd))
0044 return false;
0045
0046 platform_device_unregister(pd);
0047 pd = NULL;
0048
0049 return true;
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 void sysfb_disable(void)
0064 {
0065 mutex_lock(&disable_lock);
0066 sysfb_unregister();
0067 disabled = true;
0068 mutex_unlock(&disable_lock);
0069 }
0070 EXPORT_SYMBOL_GPL(sysfb_disable);
0071
0072 static __init int sysfb_init(void)
0073 {
0074 struct screen_info *si = &screen_info;
0075 struct simplefb_platform_data mode;
0076 const char *name;
0077 bool compatible;
0078 int ret = 0;
0079
0080 mutex_lock(&disable_lock);
0081 if (disabled)
0082 goto unlock_mutex;
0083
0084
0085 compatible = sysfb_parse_mode(si, &mode);
0086 if (compatible) {
0087 pd = sysfb_create_simplefb(si, &mode);
0088 if (!IS_ERR(pd))
0089 goto unlock_mutex;
0090 }
0091
0092
0093 if (si->orig_video_isVGA == VIDEO_TYPE_EFI)
0094 name = "efi-framebuffer";
0095 else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
0096 name = "vesa-framebuffer";
0097 else
0098 name = "platform-framebuffer";
0099
0100 pd = platform_device_alloc(name, 0);
0101 if (!pd) {
0102 ret = -ENOMEM;
0103 goto unlock_mutex;
0104 }
0105
0106 sysfb_apply_efi_quirks(pd);
0107
0108 ret = platform_device_add_data(pd, si, sizeof(*si));
0109 if (ret)
0110 goto err;
0111
0112 ret = platform_device_add(pd);
0113 if (ret)
0114 goto err;
0115
0116 goto unlock_mutex;
0117 err:
0118 platform_device_put(pd);
0119 unlock_mutex:
0120 mutex_unlock(&disable_lock);
0121 return ret;
0122 }
0123
0124
0125 device_initcall(sysfb_init);