aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 95072047396..140b9525b48 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -342,9 +342,22 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
342} 342}
343EXPORT_SYMBOL(drm_fb_helper_debug_leave); 343EXPORT_SYMBOL(drm_fb_helper_debug_leave);
344 344
345bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper)
346{
347 bool error = false;
348 int i, ret;
349 for (i = 0; i < fb_helper->crtc_count; i++) {
350 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
351 ret = drm_crtc_helper_set_config(mode_set);
352 if (ret)
353 error = true;
354 }
355 return error;
356}
357EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode);
358
345bool drm_fb_helper_force_kernel_mode(void) 359bool drm_fb_helper_force_kernel_mode(void)
346{ 360{
347 int i = 0;
348 bool ret, error = false; 361 bool ret, error = false;
349 struct drm_fb_helper *helper; 362 struct drm_fb_helper *helper;
350 363
@@ -352,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void)
352 return false; 365 return false;
353 366
354 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { 367 list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
355 for (i = 0; i < helper->crtc_count; i++) { 368 if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF)
356 struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; 369 continue;
357 ret = drm_crtc_helper_set_config(mode_set); 370
358 if (ret) 371 ret = drm_fb_helper_restore_fbdev_mode(helper);
359 error = true; 372 if (ret)
360 } 373 error = true;
361 } 374 }
362 return error; 375 return error;
363} 376}
@@ -1503,17 +1516,33 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
1503} 1516}
1504EXPORT_SYMBOL(drm_fb_helper_initial_config); 1517EXPORT_SYMBOL(drm_fb_helper_initial_config);
1505 1518
1506bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) 1519/**
1520 * drm_fb_helper_hotplug_event - respond to a hotplug notification by
1521 * probing all the outputs attached to the fb.
1522 * @fb_helper: the drm_fb_helper
1523 *
1524 * LOCKING:
1525 * Called at runtime, must take mode config lock.
1526 *
1527 * Scan the connectors attached to the fb_helper and try to put together a
1528 * setup after *notification of a change in output configuration.
1529 *
1530 * RETURNS:
1531 * 0 on success and a non-zero error code otherwise.
1532 */
1533int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
1507{ 1534{
1535 struct drm_device *dev = fb_helper->dev;
1508 int count = 0; 1536 int count = 0;
1509 u32 max_width, max_height, bpp_sel; 1537 u32 max_width, max_height, bpp_sel;
1510 bool bound = false, crtcs_bound = false; 1538 bool bound = false, crtcs_bound = false;
1511 struct drm_crtc *crtc; 1539 struct drm_crtc *crtc;
1512 1540
1513 if (!fb_helper->fb) 1541 if (!fb_helper->fb)
1514 return false; 1542 return 0;
1515 1543
1516 list_for_each_entry(crtc, &fb_helper->dev->mode_config.crtc_list, head) { 1544 mutex_lock(&dev->mode_config.mutex);
1545 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1517 if (crtc->fb) 1546 if (crtc->fb)
1518 crtcs_bound = true; 1547 crtcs_bound = true;
1519 if (crtc->fb == fb_helper->fb) 1548 if (crtc->fb == fb_helper->fb)
@@ -1522,7 +1551,8 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
1522 1551
1523 if (!bound && crtcs_bound) { 1552 if (!bound && crtcs_bound) {
1524 fb_helper->delayed_hotplug = true; 1553 fb_helper->delayed_hotplug = true;
1525 return false; 1554 mutex_unlock(&dev->mode_config.mutex);
1555 return 0;
1526 } 1556 }
1527 DRM_DEBUG_KMS("\n"); 1557 DRM_DEBUG_KMS("\n");
1528 1558
@@ -1533,6 +1563,7 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
1533 count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, 1563 count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
1534 max_height); 1564 max_height);
1535 drm_setup_crtcs(fb_helper); 1565 drm_setup_crtcs(fb_helper);
1566 mutex_unlock(&dev->mode_config.mutex);
1536 1567
1537 return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); 1568 return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
1538} 1569}