3737#include <linux/tty.h>
3838#include <linux/vga_switcheroo.h>
3939
40+ #include <drm/clients/drm_client_setup.h>
4041#include <drm/drm_crtc.h>
4142#include <drm/drm_crtc_helper.h>
4243#include <drm/drm_fb_helper.h>
5657#include "intel_fbdev_fb.h"
5758#include "intel_frontbuffer.h"
5859
59- static int intelfb_create (struct drm_fb_helper * helper ,
60- struct drm_fb_helper_surface_size * sizes );
61-
6260struct intel_fbdev {
6361 struct intel_framebuffer * fb ;
6462 struct i915_vma * vma ;
@@ -203,14 +201,13 @@ static void intelfb_set_suspend(struct drm_fb_helper *fb_helper, bool suspend)
203201}
204202
205203static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
206- .fb_probe = intelfb_create ,
207204 .fb_dirty = intelfb_dirty ,
208205 .fb_restore = intelfb_restore ,
209206 .fb_set_suspend = intelfb_set_suspend ,
210207};
211208
212- static int intelfb_create (struct drm_fb_helper * helper ,
213- struct drm_fb_helper_surface_size * sizes )
209+ int intel_fbdev_driver_fbdev_probe (struct drm_fb_helper * helper ,
210+ struct drm_fb_helper_surface_size * sizes )
214211{
215212 struct intel_fbdev * ifbdev = to_intel_fbdev (helper );
216213 struct intel_framebuffer * fb = ifbdev -> fb ;
@@ -273,6 +270,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
273270 goto out_unpin ;
274271 }
275272
273+ helper -> funcs = & intel_fb_helper_funcs ;
276274 helper -> fb = & fb -> base ;
277275
278276 info -> fbops = & intelfb_ops ;
@@ -481,174 +479,11 @@ static unsigned int intel_fbdev_color_mode(const struct drm_format_info *info)
481479 }
482480}
483481
484- static void intel_fbdev_suspend_worker (struct work_struct * work )
485- {
486- intel_fbdev_set_suspend (& container_of (work ,
487- struct drm_i915_private ,
488- display .fbdev .suspend_work )-> drm ,
489- FBINFO_STATE_RUNNING ,
490- true);
491- }
492-
493- void intel_fbdev_set_suspend (struct drm_device * dev , int state , bool synchronous )
494- {
495- struct drm_i915_private * dev_priv = to_i915 (dev );
496- struct intel_fbdev * ifbdev = dev_priv -> display .fbdev .fbdev ;
497-
498- if (!ifbdev )
499- return ;
500-
501- if (drm_WARN_ON (& dev_priv -> drm , !HAS_DISPLAY (dev_priv )))
502- return ;
503-
504- if (!ifbdev -> vma )
505- return ;
506-
507- if (synchronous ) {
508- /* Flush any pending work to turn the console on, and then
509- * wait to turn it off. It must be synchronous as we are
510- * about to suspend or unload the driver.
511- *
512- * Note that from within the work-handler, we cannot flush
513- * ourselves, so only flush outstanding work upon suspend!
514- */
515- if (state != FBINFO_STATE_RUNNING )
516- flush_work (& dev_priv -> display .fbdev .suspend_work );
517-
518- console_lock ();
519- } else {
520- /*
521- * The console lock can be pretty contented on resume due
522- * to all the printk activity. Try to keep it out of the hot
523- * path of resume if possible.
524- */
525- drm_WARN_ON (dev , state != FBINFO_STATE_RUNNING );
526- if (!console_trylock ()) {
527- /* Don't block our own workqueue as this can
528- * be run in parallel with other i915.ko tasks.
529- */
530- queue_work (dev_priv -> unordered_wq ,
531- & dev_priv -> display .fbdev .suspend_work );
532- return ;
533- }
534- }
535-
536- drm_fb_helper_set_suspend (dev -> fb_helper , state );
537- console_unlock ();
538- }
539-
540- static int intel_fbdev_restore_mode (struct drm_i915_private * dev_priv )
541- {
542- struct intel_fbdev * ifbdev = dev_priv -> display .fbdev .fbdev ;
543- struct drm_device * dev = & dev_priv -> drm ;
544- int ret ;
545-
546- if (!ifbdev )
547- return - EINVAL ;
548-
549- if (!ifbdev -> vma )
550- return - ENOMEM ;
551-
552- ret = drm_fb_helper_restore_fbdev_mode_unlocked (dev -> fb_helper );
553- if (ret )
554- return ret ;
555-
556- return 0 ;
557- }
558-
559- /*
560- * Fbdev client and struct drm_client_funcs
561- */
562-
563- static void intel_fbdev_client_unregister (struct drm_client_dev * client )
564- {
565- struct drm_fb_helper * fb_helper = drm_fb_helper_from_client (client );
566- struct drm_device * dev = fb_helper -> dev ;
567- struct pci_dev * pdev = to_pci_dev (dev -> dev );
568-
569- if (fb_helper -> info ) {
570- vga_switcheroo_client_fb_set (pdev , NULL );
571- drm_fb_helper_unregister_info (fb_helper );
572- } else {
573- drm_fb_helper_unprepare (fb_helper );
574- drm_client_release (& fb_helper -> client );
575- kfree (fb_helper );
576- }
577- }
578-
579- static int intel_fbdev_client_restore (struct drm_client_dev * client )
580- {
581- struct drm_i915_private * dev_priv = to_i915 (client -> dev );
582- int ret ;
583-
584- ret = intel_fbdev_restore_mode (dev_priv );
585- if (ret )
586- return ret ;
587-
588- vga_switcheroo_process_delayed_switch ();
589-
590- return 0 ;
591- }
592-
593- static int intel_fbdev_client_hotplug (struct drm_client_dev * client )
594- {
595- struct drm_fb_helper * fb_helper = drm_fb_helper_from_client (client );
596- struct drm_device * dev = client -> dev ;
597- struct pci_dev * pdev = to_pci_dev (dev -> dev );
598- int ret ;
599-
600- if (dev -> fb_helper )
601- return drm_fb_helper_hotplug_event (dev -> fb_helper );
602-
603- ret = drm_fb_helper_init (dev , fb_helper );
604- if (ret )
605- goto err_drm_err ;
606-
607- ret = drm_fb_helper_initial_config (fb_helper );
608- if (ret )
609- goto err_drm_fb_helper_fini ;
610-
611- vga_switcheroo_client_fb_set (pdev , fb_helper -> info );
612-
613- return 0 ;
614-
615- err_drm_fb_helper_fini :
616- drm_fb_helper_fini (fb_helper );
617- err_drm_err :
618- drm_err (dev , "Failed to setup i915 fbdev emulation (ret=%d)\n" , ret );
619- return ret ;
620- }
621-
622- static int intel_fbdev_client_suspend (struct drm_client_dev * client , bool holds_console_lock )
623- {
624- intel_fbdev_set_suspend (client -> dev , FBINFO_STATE_SUSPENDED , true);
625-
626- return 0 ;
627- }
628-
629- static int intel_fbdev_client_resume (struct drm_client_dev * client , bool holds_console_lock )
630- {
631- intel_fbdev_set_suspend (client -> dev , FBINFO_STATE_RUNNING , false);
632-
633- return 0 ;
634- }
635-
636- static const struct drm_client_funcs intel_fbdev_client_funcs = {
637- .owner = THIS_MODULE ,
638- .unregister = intel_fbdev_client_unregister ,
639- .restore = intel_fbdev_client_restore ,
640- .hotplug = intel_fbdev_client_hotplug ,
641- .suspend = intel_fbdev_client_suspend ,
642- .resume = intel_fbdev_client_resume ,
643- };
644-
645482void intel_fbdev_setup (struct drm_i915_private * i915 )
646483{
647484 struct drm_device * dev = & i915 -> drm ;
648485 struct intel_fbdev * ifbdev ;
649- struct drm_fb_helper * fb_helper ;
650486 unsigned int preferred_bpp = 0 ;
651- int ret ;
652487
653488 if (!HAS_DISPLAY (i915 ))
654489 return ;
@@ -658,31 +493,12 @@ void intel_fbdev_setup(struct drm_i915_private *i915)
658493 return ;
659494
660495 i915 -> display .fbdev .fbdev = ifbdev ;
661- INIT_WORK (& i915 -> display .fbdev .suspend_work , intel_fbdev_suspend_worker );
662496 if (intel_fbdev_init_bios (dev , ifbdev ))
663497 preferred_bpp = intel_fbdev_color_mode (ifbdev -> fb -> base .format );
664498 if (!preferred_bpp )
665499 preferred_bpp = 32 ;
666500
667- fb_helper = kzalloc (sizeof (* fb_helper ), GFP_KERNEL );
668- if (!fb_helper )
669- return ;
670- drm_fb_helper_prepare (dev , fb_helper , preferred_bpp , & intel_fb_helper_funcs );
671-
672- ret = drm_client_init (dev , & fb_helper -> client , "intel-fbdev" ,
673- & intel_fbdev_client_funcs );
674- if (ret ) {
675- drm_err (dev , "Failed to register client: %d\n" , ret );
676- goto err_drm_fb_helper_unprepare ;
677- }
678-
679- drm_client_register (& fb_helper -> client );
680-
681- return ;
682-
683- err_drm_fb_helper_unprepare :
684- drm_fb_helper_unprepare (dev -> fb_helper );
685- kfree (fb_helper );
501+ drm_client_setup_with_color_mode (dev , preferred_bpp );
686502}
687503
688504struct intel_framebuffer * intel_fbdev_framebuffer (struct intel_fbdev * fbdev )
0 commit comments