#include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h>
+static bool drm_fbdev_emulation = true;
+module_param_named(fbdev_emulation, drm_fbdev_emulation, bool, 0600);
+MODULE_PARM_DESC(fbdev_emulation,
+ "Enable legacy fbdev emulation [default=true]");
+
static LIST_HEAD(kernel_fb_helper_list);
/**
struct drm_connector *connector;
int i;
+ if (!drm_fbdev_emulation)
+ return 0;
+
mutex_lock(&dev->mode_config.mutex);
drm_for_each_connector(connector, dev) {
struct drm_fb_helper_connector *fb_helper_connector;
struct drm_fb_helper_connector **temp;
struct drm_fb_helper_connector *fb_helper_connector;
+ if (!drm_fbdev_emulation)
+ return 0;
+
WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) {
temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector *) * (fb_helper->connector_count + 1), GFP_KERNEL);
struct drm_fb_helper_connector *fb_helper_connector;
int i, j;
+ if (!drm_fbdev_emulation)
+ return 0;
+
WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
for (i = 0; i < fb_helper->connector_count; i++) {
}
EXPORT_SYMBOL(drm_fb_helper_debug_leave);
-static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
+static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
struct drm_plane *plane;
- bool error = false;
int i;
drm_warn_on_modeset_not_all_locked(dev);
if (crtc->funcs->cursor_set) {
ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0);
if (ret)
- error = true;
+ return ret;
}
ret = drm_mode_set_config_internal(mode_set);
if (ret)
- error = true;
+ return ret;
}
- return error;
+
+ return 0;
}
/**
* This should be called from driver's drm ->lastclose callback
* when implementing an fbcon on top of kms using this helper. This ensures that
* the user isn't greeted with a black screen when e.g. X dies.
+ *
+ * RETURNS:
+ * Zero if everything went ok, negative error code otherwise.
*/
-bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
+int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
- bool ret;
- bool do_delayed = false;
+ bool do_delayed;
+ int ret;
+
+ if (!drm_fbdev_emulation)
+ return -ENODEV;
drm_modeset_lock_all(dev);
ret = restore_fbdev_mode(fb_helper);
struct drm_crtc *crtc;
int i;
+ if (!drm_fbdev_emulation)
+ return 0;
+
if (!max_conn_count)
return -EINVAL;
void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
{
+ if (!drm_fbdev_emulation)
+ return;
+
if (!list_empty(&fb_helper->kernel_fb_list)) {
list_del(&fb_helper->kernel_fb_list);
if (list_empty(&kernel_fb_helper_list)) {
struct drm_device *dev = fb_helper->dev;
int count = 0;
+ if (!drm_fbdev_emulation)
+ return 0;
+
mutex_lock(&dev->mode_config.mutex);
count = drm_fb_helper_probe_connector_modes(fb_helper,
dev->mode_config.max_width,
struct drm_device *dev = fb_helper->dev;
u32 max_width, max_height;
+ if (!drm_fbdev_emulation)
+ return 0;
+
mutex_lock(&fb_helper->dev->mode_config.mutex);
if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
fb_helper->delayed_hotplug = true;