|
@@ -49,10 +49,11 @@ static LIST_HEAD(kernel_fb_helper_list);
|
|
* helper functions used by many drivers to implement the kernel mode setting
|
|
* helper functions used by many drivers to implement the kernel mode setting
|
|
* interfaces.
|
|
* interfaces.
|
|
*
|
|
*
|
|
- * Initialization is done as a three-step process with drm_fb_helper_init(),
|
|
|
|
- * drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config().
|
|
|
|
- * Drivers with fancier requirements than the default behaviour can override the
|
|
|
|
- * second step with their own code. Teardown is done with drm_fb_helper_fini().
|
|
|
|
|
|
+ * Initialization is done as a four-step process with drm_fb_helper_prepare(),
|
|
|
|
+ * drm_fb_helper_init(), drm_fb_helper_single_add_all_connectors() and
|
|
|
|
+ * drm_fb_helper_initial_config(). Drivers with fancier requirements than the
|
|
|
|
+ * default behaviour can override the third step with their own code.
|
|
|
|
+ * Teardown is done with drm_fb_helper_fini().
|
|
*
|
|
*
|
|
* At runtime drivers should restore the fbdev console by calling
|
|
* At runtime drivers should restore the fbdev console by calling
|
|
* drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They
|
|
* drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They
|
|
@@ -63,6 +64,19 @@ static LIST_HEAD(kernel_fb_helper_list);
|
|
*
|
|
*
|
|
* All other functions exported by the fb helper library can be used to
|
|
* All other functions exported by the fb helper library can be used to
|
|
* implement the fbdev driver interface by the driver.
|
|
* implement the fbdev driver interface by the driver.
|
|
|
|
+ *
|
|
|
|
+ * It is possible, though perhaps somewhat tricky, to implement race-free
|
|
|
|
+ * hotplug detection using the fbdev helpers. The drm_fb_helper_prepare()
|
|
|
|
+ * helper must be called first to initialize the minimum required to make
|
|
|
|
+ * hotplug detection work. Drivers also need to make sure to properly set up
|
|
|
|
+ * the dev->mode_config.funcs member. After calling drm_kms_helper_poll_init()
|
|
|
|
+ * it is safe to enable interrupts and start processing hotplug events. At the
|
|
|
|
+ * same time, drivers should initialize all modeset objects such as CRTCs,
|
|
|
|
+ * encoders and connectors. To finish up the fbdev helper initialization, the
|
|
|
|
+ * drm_fb_helper_init() function is called. To probe for all attached displays
|
|
|
|
+ * and set up an initial configuration using the detected hardware, drivers
|
|
|
|
+ * should call drm_fb_helper_single_add_all_connectors() followed by
|
|
|
|
+ * drm_fb_helper_initial_config().
|
|
*/
|
|
*/
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -527,6 +541,24 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
|
|
kfree(helper->crtc_info);
|
|
kfree(helper->crtc_info);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * drm_fb_helper_prepare - setup a drm_fb_helper structure
|
|
|
|
+ * @dev: DRM device
|
|
|
|
+ * @helper: driver-allocated fbdev helper structure to set up
|
|
|
|
+ * @funcs: pointer to structure of functions associate with this helper
|
|
|
|
+ *
|
|
|
|
+ * Sets up the bare minimum to make the framebuffer helper usable. This is
|
|
|
|
+ * useful to implement race-free initialization of the polling helpers.
|
|
|
|
+ */
|
|
|
|
+void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
|
|
|
+ const struct drm_fb_helper_funcs *funcs)
|
|
|
|
+{
|
|
|
|
+ INIT_LIST_HEAD(&helper->kernel_fb_list);
|
|
|
|
+ helper->funcs = funcs;
|
|
|
|
+ helper->dev = dev;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(drm_fb_helper_prepare);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* drm_fb_helper_init - initialize a drm_fb_helper structure
|
|
* drm_fb_helper_init - initialize a drm_fb_helper structure
|
|
* @dev: drm device
|
|
* @dev: drm device
|
|
@@ -539,8 +571,7 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
|
|
* nor register the fbdev. This is only done in drm_fb_helper_initial_config()
|
|
* nor register the fbdev. This is only done in drm_fb_helper_initial_config()
|
|
* to allow driver writes more control over the exact init sequence.
|
|
* to allow driver writes more control over the exact init sequence.
|
|
*
|
|
*
|
|
- * Drivers must set fb_helper->funcs before calling
|
|
|
|
- * drm_fb_helper_initial_config().
|
|
|
|
|
|
+ * Drivers must call drm_fb_helper_prepare() before calling this function.
|
|
*
|
|
*
|
|
* RETURNS:
|
|
* RETURNS:
|
|
* Zero if everything went ok, nonzero otherwise.
|
|
* Zero if everything went ok, nonzero otherwise.
|
|
@@ -555,10 +586,6 @@ int drm_fb_helper_init(struct drm_device *dev,
|
|
if (!max_conn_count)
|
|
if (!max_conn_count)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- fb_helper->dev = dev;
|
|
|
|
-
|
|
|
|
- INIT_LIST_HEAD(&fb_helper->kernel_fb_list);
|
|
|
|
-
|
|
|
|
fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
|
|
fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
|
|
if (!fb_helper->crtc_info)
|
|
if (!fb_helper->crtc_info)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|