diff mbox

[v6,6/7] efifb: Set info->fbcon_rotate_hint based on drm_get_panel_orientation_quirk

Message ID 20171125191622.16289-7-hdegoede@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Hans de Goede Nov. 25, 2017, 7:16 p.m. UTC
On some hardware the LCD panel is not mounted upright in the casing,
but rotated by 90 degrees. In this case we want the console to
automatically be rotated to compensate.

The drm subsys has a quirk table for this, use the
drm_get_panel_orientation_quirk function to get the panel orientation
and set info->fbcon_rotate_hint based on this, so that the fbcon console
on top of efifb gets automatically rotated to compensate for the panel
orientation.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/video/fbdev/Kconfig |  1 +
 drivers/video/fbdev/efifb.c | 21 ++++++++++++++++++++-
 2 files changed, 21 insertions(+), 1 deletion(-)

Comments

kernel test robot Nov. 28, 2017, 9:07 p.m. UTC | #1
Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[cannot apply to linus/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171129-001142
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: x86_64-randconfig-s1-11282357 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
   drivers/video/fbdev/efifb.c:339:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/video/fbdev/efifb.c:339:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:342:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/video/fbdev/efifb.c:345:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function)
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/DRM_MODE_PANEL_ORIENTATION_LEFT_UP +342 drivers/video/fbdev/efifb.c

   157	
   158	static int efifb_probe(struct platform_device *dev)
   159	{
   160		struct fb_info *info;
   161		int err, orientation;
   162		unsigned int size_vmode;
   163		unsigned int size_remap;
   164		unsigned int size_total;
   165		char *option = NULL;
   166	
   167		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   168			return -ENODEV;
   169	
   170		if (fb_get_options("efifb", &option))
   171			return -ENODEV;
   172		efifb_setup(option);
   173	
   174		/* We don't get linelength from UGA Draw Protocol, only from
   175		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   176		 * passed in from the user, we really can't use the framebuffer.
   177		 */
   178		if (!screen_info.lfb_linelength)
   179			return -ENODEV;
   180	
   181		if (!screen_info.lfb_depth)
   182			screen_info.lfb_depth = 32;
   183		if (!screen_info.pages)
   184			screen_info.pages = 1;
   185		if (!fb_base_is_valid()) {
   186			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   187			return -ENODEV;
   188		}
   189		printk(KERN_INFO "efifb: probing for efifb\n");
   190	
   191		/* just assume they're all unset if any are */
   192		if (!screen_info.blue_size) {
   193			screen_info.blue_size = 8;
   194			screen_info.blue_pos = 0;
   195			screen_info.green_size = 8;
   196			screen_info.green_pos = 8;
   197			screen_info.red_size = 8;
   198			screen_info.red_pos = 16;
   199			screen_info.rsvd_size = 8;
   200			screen_info.rsvd_pos = 24;
   201		}
   202	
   203		efifb_fix.smem_start = screen_info.lfb_base;
   204	
   205		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   206			u64 ext_lfb_base;
   207	
   208			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   209			efifb_fix.smem_start |= ext_lfb_base;
   210		}
   211	
   212		if (bar_resource &&
   213		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   214			dev_info(&efifb_pci_dev->dev,
   215				 "BAR has moved, updating efifb address\n");
   216			efifb_fix.smem_start = bar_resource->start + bar_offset;
   217		}
   218	
   219		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   220		efifb_defined.xres = screen_info.lfb_width;
   221		efifb_defined.yres = screen_info.lfb_height;
   222		efifb_fix.line_length = screen_info.lfb_linelength;
   223	
   224		/*   size_vmode -- that is the amount of memory needed for the
   225		 *                 used video mode, i.e. the minimum amount of
   226		 *                 memory we need. */
   227		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   228	
   229		/*   size_total -- all video memory we have. Used for
   230		 *                 entries, ressource allocation and bounds
   231		 *                 checking. */
   232		size_total = screen_info.lfb_size;
   233		if (size_total < size_vmode)
   234			size_total = size_vmode;
   235	
   236		/*   size_remap -- the amount of video memory we are going to
   237		 *                 use for efifb.  With modern cards it is no
   238		 *                 option to simply use size_total as that
   239		 *                 wastes plenty of kernel address space. */
   240		size_remap  = size_vmode * 2;
   241		if (size_remap > size_total)
   242			size_remap = size_total;
   243		if (size_remap % PAGE_SIZE)
   244			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   245		efifb_fix.smem_len = size_remap;
   246	
   247		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   248			request_mem_succeeded = true;
   249		} else {
   250			/* We cannot make this fatal. Sometimes this comes from magic
   251			   spaces our resource handlers simply don't know about */
   252			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   253				efifb_fix.smem_start);
   254		}
   255	
   256		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   257		if (!info) {
   258			pr_err("efifb: cannot allocate framebuffer\n");
   259			err = -ENOMEM;
   260			goto err_release_mem;
   261		}
   262		platform_set_drvdata(dev, info);
   263		info->pseudo_palette = info->par;
   264		info->par = NULL;
   265	
   266		info->apertures = alloc_apertures(1);
   267		if (!info->apertures) {
   268			err = -ENOMEM;
   269			goto err_release_fb;
   270		}
   271		info->apertures->ranges[0].base = efifb_fix.smem_start;
   272		info->apertures->ranges[0].size = size_remap;
   273	
   274		if (nowc)
   275			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   276		else
   277			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   278		if (!info->screen_base) {
   279			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   280				efifb_fix.smem_len, efifb_fix.smem_start);
   281			err = -EIO;
   282			goto err_release_fb;
   283		}
   284	
   285		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   286		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   287		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   288		       efifb_defined.xres, efifb_defined.yres,
   289		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   290		       screen_info.pages);
   291	
   292		efifb_defined.xres_virtual = efifb_defined.xres;
   293		efifb_defined.yres_virtual = efifb_fix.smem_len /
   294						efifb_fix.line_length;
   295		pr_info("efifb: scrolling: redraw\n");
   296		efifb_defined.yres_virtual = efifb_defined.yres;
   297	
   298		/* some dummy values for timing to make fbset happy */
   299		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   300						1000 / efifb_defined.yres;
   301		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   302		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   303	
   304		efifb_defined.red.offset    = screen_info.red_pos;
   305		efifb_defined.red.length    = screen_info.red_size;
   306		efifb_defined.green.offset  = screen_info.green_pos;
   307		efifb_defined.green.length  = screen_info.green_size;
   308		efifb_defined.blue.offset   = screen_info.blue_pos;
   309		efifb_defined.blue.length   = screen_info.blue_size;
   310		efifb_defined.transp.offset = screen_info.rsvd_pos;
   311		efifb_defined.transp.length = screen_info.rsvd_size;
   312	
   313		pr_info("efifb: %s: "
   314		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   315		       "Truecolor",
   316		       screen_info.rsvd_size,
   317		       screen_info.red_size,
   318		       screen_info.green_size,
   319		       screen_info.blue_size,
   320		       screen_info.rsvd_pos,
   321		       screen_info.red_pos,
   322		       screen_info.green_pos,
   323		       screen_info.blue_pos);
   324	
   325		efifb_fix.ypanstep  = 0;
   326		efifb_fix.ywrapstep = 0;
   327	
   328		info->fbops = &efifb_ops;
   329		info->var = efifb_defined;
   330		info->fix = efifb_fix;
   331		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   332	
   333		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   334							      efifb_defined.yres);
   335		switch (orientation) {
   336		default:
   337			info->fbcon_rotate_hint = FB_ROTATE_UR;
   338			break;
 > 339		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   340			info->fbcon_rotate_hint = FB_ROTATE_UD;
   341			break;
 > 342		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   343			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   344			break;
 > 345		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   346			info->fbcon_rotate_hint = FB_ROTATE_CW;
   347			break;
   348		}
   349	
   350		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   351		if (err) {
   352			pr_err("efifb: cannot add sysfs attrs\n");
   353			goto err_unmap;
   354		}
   355		err = fb_alloc_cmap(&info->cmap, 256, 0);
   356		if (err < 0) {
   357			pr_err("efifb: cannot allocate colormap\n");
   358			goto err_groups;
   359		}
   360		err = register_framebuffer(info);
   361		if (err < 0) {
   362			pr_err("efifb: cannot register framebuffer\n");
   363			goto err_fb_dealoc;
   364		}
   365		fb_info(info, "%s frame buffer device\n", info->fix.id);
   366		return 0;
   367	
   368	err_fb_dealoc:
   369		fb_dealloc_cmap(&info->cmap);
   370	err_groups:
   371		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   372	err_unmap:
   373		iounmap(info->screen_base);
   374	err_release_fb:
   375		framebuffer_release(info);
   376	err_release_mem:
   377		if (request_mem_succeeded)
   378			release_mem_region(efifb_fix.smem_start, size_total);
   379		return err;
   380	}
   381	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot Nov. 28, 2017, 10:19 p.m. UTC | #2
Hi Hans,

I love your patch! Yet something to improve:

[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.15-rc1 next-20171128]
[cannot apply to linus/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Hans-de-Goede/drm-fbdev-Panel-orientation-connector-property-support/20171129-001142
base:   git://people.freedesktop.org/~airlied/linux.git drm-next
config: x86_64-kexec (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/video/fbdev/efifb.c: In function 'efifb_probe':
>> drivers/video/fbdev/efifb.c:339:7: error: 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PRESENT_BOTTOM_FIELD'?
     case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PRESENT_BOTTOM_FIELD
   drivers/video/fbdev/efifb.c:339:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/video/fbdev/efifb.c:342:7: error: 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP'?
     case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP
>> drivers/video/fbdev/efifb.c:345:7: error: 'DRM_MODE_PANEL_ORIENTATION_RIGHT_UP' undeclared (first use in this function); did you mean 'DRM_MODE_PANEL_ORIENTATION_LEFT_UP'?
     case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          DRM_MODE_PANEL_ORIENTATION_LEFT_UP

vim +339 drivers/video/fbdev/efifb.c

   157	
   158	static int efifb_probe(struct platform_device *dev)
   159	{
   160		struct fb_info *info;
   161		int err, orientation;
   162		unsigned int size_vmode;
   163		unsigned int size_remap;
   164		unsigned int size_total;
   165		char *option = NULL;
   166	
   167		if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
   168			return -ENODEV;
   169	
   170		if (fb_get_options("efifb", &option))
   171			return -ENODEV;
   172		efifb_setup(option);
   173	
   174		/* We don't get linelength from UGA Draw Protocol, only from
   175		 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
   176		 * passed in from the user, we really can't use the framebuffer.
   177		 */
   178		if (!screen_info.lfb_linelength)
   179			return -ENODEV;
   180	
   181		if (!screen_info.lfb_depth)
   182			screen_info.lfb_depth = 32;
   183		if (!screen_info.pages)
   184			screen_info.pages = 1;
   185		if (!fb_base_is_valid()) {
   186			printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
   187			return -ENODEV;
   188		}
   189		printk(KERN_INFO "efifb: probing for efifb\n");
   190	
   191		/* just assume they're all unset if any are */
   192		if (!screen_info.blue_size) {
   193			screen_info.blue_size = 8;
   194			screen_info.blue_pos = 0;
   195			screen_info.green_size = 8;
   196			screen_info.green_pos = 8;
   197			screen_info.red_size = 8;
   198			screen_info.red_pos = 16;
   199			screen_info.rsvd_size = 8;
   200			screen_info.rsvd_pos = 24;
   201		}
   202	
   203		efifb_fix.smem_start = screen_info.lfb_base;
   204	
   205		if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
   206			u64 ext_lfb_base;
   207	
   208			ext_lfb_base = (u64)(unsigned long)screen_info.ext_lfb_base << 32;
   209			efifb_fix.smem_start |= ext_lfb_base;
   210		}
   211	
   212		if (bar_resource &&
   213		    bar_resource->start + bar_offset != efifb_fix.smem_start) {
   214			dev_info(&efifb_pci_dev->dev,
   215				 "BAR has moved, updating efifb address\n");
   216			efifb_fix.smem_start = bar_resource->start + bar_offset;
   217		}
   218	
   219		efifb_defined.bits_per_pixel = screen_info.lfb_depth;
   220		efifb_defined.xres = screen_info.lfb_width;
   221		efifb_defined.yres = screen_info.lfb_height;
   222		efifb_fix.line_length = screen_info.lfb_linelength;
   223	
   224		/*   size_vmode -- that is the amount of memory needed for the
   225		 *                 used video mode, i.e. the minimum amount of
   226		 *                 memory we need. */
   227		size_vmode = efifb_defined.yres * efifb_fix.line_length;
   228	
   229		/*   size_total -- all video memory we have. Used for
   230		 *                 entries, ressource allocation and bounds
   231		 *                 checking. */
   232		size_total = screen_info.lfb_size;
   233		if (size_total < size_vmode)
   234			size_total = size_vmode;
   235	
   236		/*   size_remap -- the amount of video memory we are going to
   237		 *                 use for efifb.  With modern cards it is no
   238		 *                 option to simply use size_total as that
   239		 *                 wastes plenty of kernel address space. */
   240		size_remap  = size_vmode * 2;
   241		if (size_remap > size_total)
   242			size_remap = size_total;
   243		if (size_remap % PAGE_SIZE)
   244			size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
   245		efifb_fix.smem_len = size_remap;
   246	
   247		if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
   248			request_mem_succeeded = true;
   249		} else {
   250			/* We cannot make this fatal. Sometimes this comes from magic
   251			   spaces our resource handlers simply don't know about */
   252			pr_warn("efifb: cannot reserve video memory at 0x%lx\n",
   253				efifb_fix.smem_start);
   254		}
   255	
   256		info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
   257		if (!info) {
   258			pr_err("efifb: cannot allocate framebuffer\n");
   259			err = -ENOMEM;
   260			goto err_release_mem;
   261		}
   262		platform_set_drvdata(dev, info);
   263		info->pseudo_palette = info->par;
   264		info->par = NULL;
   265	
   266		info->apertures = alloc_apertures(1);
   267		if (!info->apertures) {
   268			err = -ENOMEM;
   269			goto err_release_fb;
   270		}
   271		info->apertures->ranges[0].base = efifb_fix.smem_start;
   272		info->apertures->ranges[0].size = size_remap;
   273	
   274		if (nowc)
   275			info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
   276		else
   277			info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
   278		if (!info->screen_base) {
   279			pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
   280				efifb_fix.smem_len, efifb_fix.smem_start);
   281			err = -EIO;
   282			goto err_release_fb;
   283		}
   284	
   285		pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
   286		       efifb_fix.smem_start, size_remap/1024, size_total/1024);
   287		pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
   288		       efifb_defined.xres, efifb_defined.yres,
   289		       efifb_defined.bits_per_pixel, efifb_fix.line_length,
   290		       screen_info.pages);
   291	
   292		efifb_defined.xres_virtual = efifb_defined.xres;
   293		efifb_defined.yres_virtual = efifb_fix.smem_len /
   294						efifb_fix.line_length;
   295		pr_info("efifb: scrolling: redraw\n");
   296		efifb_defined.yres_virtual = efifb_defined.yres;
   297	
   298		/* some dummy values for timing to make fbset happy */
   299		efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
   300						1000 / efifb_defined.yres;
   301		efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
   302		efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
   303	
   304		efifb_defined.red.offset    = screen_info.red_pos;
   305		efifb_defined.red.length    = screen_info.red_size;
   306		efifb_defined.green.offset  = screen_info.green_pos;
   307		efifb_defined.green.length  = screen_info.green_size;
   308		efifb_defined.blue.offset   = screen_info.blue_pos;
   309		efifb_defined.blue.length   = screen_info.blue_size;
   310		efifb_defined.transp.offset = screen_info.rsvd_pos;
   311		efifb_defined.transp.length = screen_info.rsvd_size;
   312	
   313		pr_info("efifb: %s: "
   314		       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
   315		       "Truecolor",
   316		       screen_info.rsvd_size,
   317		       screen_info.red_size,
   318		       screen_info.green_size,
   319		       screen_info.blue_size,
   320		       screen_info.rsvd_pos,
   321		       screen_info.red_pos,
   322		       screen_info.green_pos,
   323		       screen_info.blue_pos);
   324	
   325		efifb_fix.ypanstep  = 0;
   326		efifb_fix.ywrapstep = 0;
   327	
   328		info->fbops = &efifb_ops;
   329		info->var = efifb_defined;
   330		info->fix = efifb_fix;
   331		info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
   332	
   333		orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
   334							      efifb_defined.yres);
   335		switch (orientation) {
   336		default:
   337			info->fbcon_rotate_hint = FB_ROTATE_UR;
   338			break;
 > 339		case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
   340			info->fbcon_rotate_hint = FB_ROTATE_UD;
   341			break;
 > 342		case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
   343			info->fbcon_rotate_hint = FB_ROTATE_CCW;
   344			break;
 > 345		case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
   346			info->fbcon_rotate_hint = FB_ROTATE_CW;
   347			break;
   348		}
   349	
   350		err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
   351		if (err) {
   352			pr_err("efifb: cannot add sysfs attrs\n");
   353			goto err_unmap;
   354		}
   355		err = fb_alloc_cmap(&info->cmap, 256, 0);
   356		if (err < 0) {
   357			pr_err("efifb: cannot allocate colormap\n");
   358			goto err_groups;
   359		}
   360		err = register_framebuffer(info);
   361		if (err < 0) {
   362			pr_err("efifb: cannot register framebuffer\n");
   363			goto err_fb_dealoc;
   364		}
   365		fb_info(info, "%s frame buffer device\n", info->fix.id);
   366		return 0;
   367	
   368	err_fb_dealoc:
   369		fb_dealloc_cmap(&info->cmap);
   370	err_groups:
   371		sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
   372	err_unmap:
   373		iounmap(info->screen_base);
   374	err_release_fb:
   375		framebuffer_release(info);
   376	err_release_mem:
   377		if (request_mem_succeeded)
   378			release_mem_region(efifb_fix.smem_start, size_total);
   379		return err;
   380	}
   381	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 5e58f5ec0a28..c4a90c497839 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -772,6 +772,7 @@  config FB_VESA
 config FB_EFI
 	bool "EFI-based Framebuffer Support"
 	depends on (FB = y) && !IA64 && EFI
+	select DRM_PANEL_ORIENTATION_QUIRKS
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index d1bf9c2a78a7..88697ab1005b 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -16,6 +16,8 @@ 
 #include <linux/screen_info.h>
 #include <video/vga.h>
 #include <asm/efi.h>
+#include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
+#include <drm/drm_mode.h>  /* For DRM_MODE_PANEL_ORIENTATION_* */
 
 static bool request_mem_succeeded = false;
 static bool nowc = false;
@@ -157,7 +159,7 @@  static u64 bar_offset;
 static int efifb_probe(struct platform_device *dev)
 {
 	struct fb_info *info;
-	int err;
+	int err, orientation;
 	unsigned int size_vmode;
 	unsigned int size_remap;
 	unsigned int size_total;
@@ -329,6 +331,23 @@  static int efifb_probe(struct platform_device *dev)
 	info->fix = efifb_fix;
 	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
 
+	orientation = drm_get_panel_orientation_quirk(efifb_defined.xres,
+						      efifb_defined.yres);
+	switch (orientation) {
+	default:
+		info->fbcon_rotate_hint = FB_ROTATE_UR;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_UD;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CCW;
+		break;
+	case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
+		info->fbcon_rotate_hint = FB_ROTATE_CW;
+		break;
+	}
+
 	err = sysfs_create_groups(&dev->dev.kobj, efifb_groups);
 	if (err) {
 		pr_err("efifb: cannot add sysfs attrs\n");