diff options
author | Dave Airlie <airlied@redhat.com> | 2016-05-08 20:16:50 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-05-08 20:16:50 -0400 |
commit | 2958cf0ee2232cddf06cc9efaf143a0919b266f5 (patch) | |
tree | 7526fcfc3c3b923ee646417531be13e615d74077 | |
parent | fd50c3a0326152d97ef02f0d55ee48d7ae66d73f (diff) | |
parent | 8863dc7f5642737e49ff681cbb842d2c614bdcf4 (diff) |
Merge tag 'topic/drm-misc-2016-05-08' of git://anongit.freedesktop.org/drm-intel into drm-next
Refcounting is hard, so here's a quick pull request with the one-liner to
fix up i915. Otherwise just a few other small things I picked up. Plus the
regression fix from Marten for rmfb behaviour that lingered around forever
since no testers. Feel free to cherry-pick that over to drm-fixes, but
given that there's not many who seemed to have cared, meh.
* tag 'topic/drm-misc-2016-05-08' of git://anongit.freedesktop.org/drm-intel:
drm/i915: Correctly refcount connectors in hw state readou
drm/panel: Flesh out kerneldoc
drm: Add gpu.tmpl docbook to MAINTAINERS entry
drm/core: Do not preserve framebuffer on rmfb, v4.
drm: Fix up markup fumble
drm/fb_helper: Fix a few typos
-rw-r--r-- | Documentation/DocBook/gpu.tmpl | 12 | ||||
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 63 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_panel.c | 61 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 5 | ||||
-rw-r--r-- | include/drm/drm_modeset_helper_vtables.h | 2 | ||||
-rw-r--r-- | include/drm/drm_panel.h | 59 |
8 files changed, 195 insertions, 14 deletions
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index 56386d3a1b2e..9dd48f7490df 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl | |||
@@ -1671,17 +1671,23 @@ void intel_crt_init(struct drm_device *dev) | |||
1671 | !Pdrivers/gpu/drm/drm_crtc.c Tile group | 1671 | !Pdrivers/gpu/drm/drm_crtc.c Tile group |
1672 | </sect2> | 1672 | </sect2> |
1673 | <sect2> | 1673 | <sect2> |
1674 | <title>Bridges</title> | 1674 | <title>Bridges</title> |
1675 | <sect3> | 1675 | <sect3> |
1676 | <title>Overview</title> | 1676 | <title>Overview</title> |
1677 | !Pdrivers/gpu/drm/drm_bridge.c overview | 1677 | !Pdrivers/gpu/drm/drm_bridge.c overview |
1678 | </sect3> | 1678 | </sect3> |
1679 | <sect3> | 1679 | <sect3> |
1680 | <title>Default bridge callback sequence</title> | 1680 | <title>Default bridge callback sequence</title> |
1681 | !Pdrivers/gpu/drm/drm_bridge.c bridge callbacks | 1681 | !Pdrivers/gpu/drm/drm_bridge.c bridge callbacks |
1682 | </sect3> | 1682 | </sect3> |
1683 | !Edrivers/gpu/drm/drm_bridge.c | 1683 | !Edrivers/gpu/drm/drm_bridge.c |
1684 | </sect2> | 1684 | </sect2> |
1685 | <sect2> | ||
1686 | <title>Panel Helper Reference</title> | ||
1687 | !Iinclude/drm/drm_panel.h | ||
1688 | !Edrivers/gpu/drm/drm_panel.c | ||
1689 | !Pdrivers/gpu/drm/drm_panel.c drm panel | ||
1690 | </sect2> | ||
1685 | </sect1> | 1691 | </sect1> |
1686 | 1692 | ||
1687 | <!-- Internals: kms properties --> | 1693 | <!-- Internals: kms properties --> |
diff --git a/MAINTAINERS b/MAINTAINERS index e6ee4ecf34b0..33181d862e5a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3765,6 +3765,7 @@ T: git git://people.freedesktop.org/~airlied/linux | |||
3765 | S: Maintained | 3765 | S: Maintained |
3766 | F: drivers/gpu/drm/ | 3766 | F: drivers/gpu/drm/ |
3767 | F: drivers/gpu/vga/ | 3767 | F: drivers/gpu/vga/ |
3768 | F: Documentation/DocBook/gpu.* | ||
3768 | F: include/drm/ | 3769 | F: include/drm/ |
3769 | F: include/uapi/drm/ | 3770 | F: include/uapi/drm/ |
3770 | 3771 | ||
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index a9c0a4348322..70f9c682d144 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -3462,6 +3462,24 @@ int drm_mode_addfb2(struct drm_device *dev, | |||
3462 | return 0; | 3462 | return 0; |
3463 | } | 3463 | } |
3464 | 3464 | ||
3465 | struct drm_mode_rmfb_work { | ||
3466 | struct work_struct work; | ||
3467 | struct list_head fbs; | ||
3468 | }; | ||
3469 | |||
3470 | static void drm_mode_rmfb_work_fn(struct work_struct *w) | ||
3471 | { | ||
3472 | struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work); | ||
3473 | |||
3474 | while (!list_empty(&arg->fbs)) { | ||
3475 | struct drm_framebuffer *fb = | ||
3476 | list_first_entry(&arg->fbs, typeof(*fb), filp_head); | ||
3477 | |||
3478 | list_del_init(&fb->filp_head); | ||
3479 | drm_framebuffer_remove(fb); | ||
3480 | } | ||
3481 | } | ||
3482 | |||
3465 | /** | 3483 | /** |
3466 | * drm_mode_rmfb - remove an FB from the configuration | 3484 | * drm_mode_rmfb - remove an FB from the configuration |
3467 | * @dev: drm device for the ioctl | 3485 | * @dev: drm device for the ioctl |
@@ -3502,12 +3520,29 @@ int drm_mode_rmfb(struct drm_device *dev, | |||
3502 | list_del_init(&fb->filp_head); | 3520 | list_del_init(&fb->filp_head); |
3503 | mutex_unlock(&file_priv->fbs_lock); | 3521 | mutex_unlock(&file_priv->fbs_lock); |
3504 | 3522 | ||
3505 | /* we now own the reference that was stored in the fbs list */ | ||
3506 | drm_framebuffer_unreference(fb); | ||
3507 | |||
3508 | /* drop the reference we picked up in framebuffer lookup */ | 3523 | /* drop the reference we picked up in framebuffer lookup */ |
3509 | drm_framebuffer_unreference(fb); | 3524 | drm_framebuffer_unreference(fb); |
3510 | 3525 | ||
3526 | /* | ||
3527 | * we now own the reference that was stored in the fbs list | ||
3528 | * | ||
3529 | * drm_framebuffer_remove may fail with -EINTR on pending signals, | ||
3530 | * so run this in a separate stack as there's no way to correctly | ||
3531 | * handle this after the fb is already removed from the lookup table. | ||
3532 | */ | ||
3533 | if (drm_framebuffer_read_refcount(fb) > 1) { | ||
3534 | struct drm_mode_rmfb_work arg; | ||
3535 | |||
3536 | INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn); | ||
3537 | INIT_LIST_HEAD(&arg.fbs); | ||
3538 | list_add_tail(&fb->filp_head, &arg.fbs); | ||
3539 | |||
3540 | schedule_work(&arg.work); | ||
3541 | flush_work(&arg.work); | ||
3542 | destroy_work_on_stack(&arg.work); | ||
3543 | } else | ||
3544 | drm_framebuffer_unreference(fb); | ||
3545 | |||
3511 | return 0; | 3546 | return 0; |
3512 | 3547 | ||
3513 | fail_unref: | 3548 | fail_unref: |
@@ -3657,7 +3692,6 @@ out_err1: | |||
3657 | return ret; | 3692 | return ret; |
3658 | } | 3693 | } |
3659 | 3694 | ||
3660 | |||
3661 | /** | 3695 | /** |
3662 | * drm_fb_release - remove and free the FBs on this file | 3696 | * drm_fb_release - remove and free the FBs on this file |
3663 | * @priv: drm file for the ioctl | 3697 | * @priv: drm file for the ioctl |
@@ -3672,6 +3706,9 @@ out_err1: | |||
3672 | void drm_fb_release(struct drm_file *priv) | 3706 | void drm_fb_release(struct drm_file *priv) |
3673 | { | 3707 | { |
3674 | struct drm_framebuffer *fb, *tfb; | 3708 | struct drm_framebuffer *fb, *tfb; |
3709 | struct drm_mode_rmfb_work arg; | ||
3710 | |||
3711 | INIT_LIST_HEAD(&arg.fbs); | ||
3675 | 3712 | ||
3676 | /* | 3713 | /* |
3677 | * When the file gets released that means no one else can access the fb | 3714 | * When the file gets released that means no one else can access the fb |
@@ -3684,10 +3721,22 @@ void drm_fb_release(struct drm_file *priv) | |||
3684 | * at it any more. | 3721 | * at it any more. |
3685 | */ | 3722 | */ |
3686 | list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { | 3723 | list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { |
3687 | list_del_init(&fb->filp_head); | 3724 | if (drm_framebuffer_read_refcount(fb) > 1) { |
3725 | list_move_tail(&fb->filp_head, &arg.fbs); | ||
3726 | } else { | ||
3727 | list_del_init(&fb->filp_head); | ||
3688 | 3728 | ||
3689 | /* This drops the fpriv->fbs reference. */ | 3729 | /* This drops the fpriv->fbs reference. */ |
3690 | drm_framebuffer_unreference(fb); | 3730 | drm_framebuffer_unreference(fb); |
3731 | } | ||
3732 | } | ||
3733 | |||
3734 | if (!list_empty(&arg.fbs)) { | ||
3735 | INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn); | ||
3736 | |||
3737 | schedule_work(&arg.work); | ||
3738 | flush_work(&arg.work); | ||
3739 | destroy_work_on_stack(&arg.work); | ||
3691 | } | 3740 | } |
3692 | } | 3741 | } |
3693 | 3742 | ||
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 0bb3d4bee24c..385284bc773c 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -2177,8 +2177,8 @@ out: | |||
2177 | * cmdline option. | 2177 | * cmdline option. |
2178 | * | 2178 | * |
2179 | * The other option is to just disable fbdev emulation since very likely the | 2179 | * The other option is to just disable fbdev emulation since very likely the |
2180 | * first modest from userspace will crash in the same way, and is even easier to | 2180 | * first modeset from userspace will crash in the same way, and is even easier |
2181 | * debug. This can be done by setting the drm_kms_helper.fbdev_emulation=0 | 2181 | * to debug. This can be done by setting the drm_kms_helper.fbdev_emulation=0 |
2182 | * kernel cmdline option. | 2182 | * kernel cmdline option. |
2183 | * | 2183 | * |
2184 | * RETURNS: | 2184 | * RETURNS: |
@@ -2223,7 +2223,7 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config); | |||
2223 | * hotplug interrupt). | 2223 | * hotplug interrupt). |
2224 | * | 2224 | * |
2225 | * Note that drivers may call this even before calling | 2225 | * Note that drivers may call this even before calling |
2226 | * drm_fb_helper_initial_config but only aftert drm_fb_helper_init. This allows | 2226 | * drm_fb_helper_initial_config but only after drm_fb_helper_init. This allows |
2227 | * for a race-free fbcon setup and will make sure that the fbdev emulation will | 2227 | * for a race-free fbcon setup and will make sure that the fbdev emulation will |
2228 | * not miss any hotplug events. | 2228 | * not miss any hotplug events. |
2229 | * | 2229 | * |
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c index 2ef988e037b7..3dfe3c886502 100644 --- a/drivers/gpu/drm/drm_panel.c +++ b/drivers/gpu/drm/drm_panel.c | |||
@@ -30,12 +30,36 @@ | |||
30 | static DEFINE_MUTEX(panel_lock); | 30 | static DEFINE_MUTEX(panel_lock); |
31 | static LIST_HEAD(panel_list); | 31 | static LIST_HEAD(panel_list); |
32 | 32 | ||
33 | /** | ||
34 | * DOC: drm panel | ||
35 | * | ||
36 | * The DRM panel helpers allow drivers to register panel objects with a | ||
37 | * central registry and provide functions to retrieve those panels in display | ||
38 | * drivers. | ||
39 | */ | ||
40 | |||
41 | /** | ||
42 | * drm_panel_init - initialize a panel | ||
43 | * @panel: DRM panel | ||
44 | * | ||
45 | * Sets up internal fields of the panel so that it can subsequently be added | ||
46 | * to the registry. | ||
47 | */ | ||
33 | void drm_panel_init(struct drm_panel *panel) | 48 | void drm_panel_init(struct drm_panel *panel) |
34 | { | 49 | { |
35 | INIT_LIST_HEAD(&panel->list); | 50 | INIT_LIST_HEAD(&panel->list); |
36 | } | 51 | } |
37 | EXPORT_SYMBOL(drm_panel_init); | 52 | EXPORT_SYMBOL(drm_panel_init); |
38 | 53 | ||
54 | /** | ||
55 | * drm_panel_add - add a panel to the global registry | ||
56 | * @panel: panel to add | ||
57 | * | ||
58 | * Add a panel to the global registry so that it can be looked up by display | ||
59 | * drivers. | ||
60 | * | ||
61 | * Return: 0 on success or a negative error code on failure. | ||
62 | */ | ||
39 | int drm_panel_add(struct drm_panel *panel) | 63 | int drm_panel_add(struct drm_panel *panel) |
40 | { | 64 | { |
41 | mutex_lock(&panel_lock); | 65 | mutex_lock(&panel_lock); |
@@ -46,6 +70,12 @@ int drm_panel_add(struct drm_panel *panel) | |||
46 | } | 70 | } |
47 | EXPORT_SYMBOL(drm_panel_add); | 71 | EXPORT_SYMBOL(drm_panel_add); |
48 | 72 | ||
73 | /** | ||
74 | * drm_panel_remove - remove a panel from the global registry | ||
75 | * @panel: DRM panel | ||
76 | * | ||
77 | * Removes a panel from the global registry. | ||
78 | */ | ||
49 | void drm_panel_remove(struct drm_panel *panel) | 79 | void drm_panel_remove(struct drm_panel *panel) |
50 | { | 80 | { |
51 | mutex_lock(&panel_lock); | 81 | mutex_lock(&panel_lock); |
@@ -54,6 +84,18 @@ void drm_panel_remove(struct drm_panel *panel) | |||
54 | } | 84 | } |
55 | EXPORT_SYMBOL(drm_panel_remove); | 85 | EXPORT_SYMBOL(drm_panel_remove); |
56 | 86 | ||
87 | /** | ||
88 | * drm_panel_attach - attach a panel to a connector | ||
89 | * @panel: DRM panel | ||
90 | * @connector: DRM connector | ||
91 | * | ||
92 | * After obtaining a pointer to a DRM panel a display driver calls this | ||
93 | * function to attach a panel to a connector. | ||
94 | * | ||
95 | * An error is returned if the panel is already attached to another connector. | ||
96 | * | ||
97 | * Return: 0 on success or a negative error code on failure. | ||
98 | */ | ||
57 | int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector) | 99 | int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector) |
58 | { | 100 | { |
59 | if (panel->connector) | 101 | if (panel->connector) |
@@ -66,6 +108,15 @@ int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector) | |||
66 | } | 108 | } |
67 | EXPORT_SYMBOL(drm_panel_attach); | 109 | EXPORT_SYMBOL(drm_panel_attach); |
68 | 110 | ||
111 | /** | ||
112 | * drm_panel_detach - detach a panel from a connector | ||
113 | * @panel: DRM panel | ||
114 | * | ||
115 | * Detaches a panel from the connector it is attached to. If a panel is not | ||
116 | * attached to any connector this is effectively a no-op. | ||
117 | * | ||
118 | * Return: 0 on success or a negative error code on failure. | ||
119 | */ | ||
69 | int drm_panel_detach(struct drm_panel *panel) | 120 | int drm_panel_detach(struct drm_panel *panel) |
70 | { | 121 | { |
71 | panel->connector = NULL; | 122 | panel->connector = NULL; |
@@ -76,6 +127,16 @@ int drm_panel_detach(struct drm_panel *panel) | |||
76 | EXPORT_SYMBOL(drm_panel_detach); | 127 | EXPORT_SYMBOL(drm_panel_detach); |
77 | 128 | ||
78 | #ifdef CONFIG_OF | 129 | #ifdef CONFIG_OF |
130 | /** | ||
131 | * of_drm_find_panel - look up a panel using a device tree node | ||
132 | * @np: device tree node of the panel | ||
133 | * | ||
134 | * Searches the set of registered panels for one that matches the given device | ||
135 | * tree node. If a matching panel is found, return a pointer to it. | ||
136 | * | ||
137 | * Return: A pointer to the panel registered for the specified device tree | ||
138 | * node or NULL if no panel matching the device tree node can be found. | ||
139 | */ | ||
79 | struct drm_panel *of_drm_find_panel(struct device_node *np) | 140 | struct drm_panel *of_drm_find_panel(struct device_node *np) |
80 | { | 141 | { |
81 | struct drm_panel *panel; | 142 | struct drm_panel *panel; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 73299f9e77a8..a297e1ffafb5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -12032,11 +12032,16 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev) | |||
12032 | struct intel_connector *connector; | 12032 | struct intel_connector *connector; |
12033 | 12033 | ||
12034 | for_each_intel_connector(dev, connector) { | 12034 | for_each_intel_connector(dev, connector) { |
12035 | if (connector->base.state->crtc) | ||
12036 | drm_connector_unreference(&connector->base); | ||
12037 | |||
12035 | if (connector->base.encoder) { | 12038 | if (connector->base.encoder) { |
12036 | connector->base.state->best_encoder = | 12039 | connector->base.state->best_encoder = |
12037 | connector->base.encoder; | 12040 | connector->base.encoder; |
12038 | connector->base.state->crtc = | 12041 | connector->base.state->crtc = |
12039 | connector->base.encoder->crtc; | 12042 | connector->base.encoder->crtc; |
12043 | |||
12044 | drm_connector_reference(&connector->base); | ||
12040 | } else { | 12045 | } else { |
12041 | connector->base.state->best_encoder = NULL; | 12046 | connector->base.state->best_encoder = NULL; |
12042 | connector->base.state->crtc = NULL; | 12047 | connector->base.state->crtc = NULL; |
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index b61c2d45192e..d4619dc2eecb 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h | |||
@@ -672,7 +672,7 @@ struct drm_connector_helper_funcs { | |||
672 | * fixed panel can also manually add specific modes using | 672 | * fixed panel can also manually add specific modes using |
673 | * drm_mode_probed_add(). Drivers which manually add modes should also | 673 | * drm_mode_probed_add(). Drivers which manually add modes should also |
674 | * make sure that the @display_info, @width_mm and @height_mm fields of the | 674 | * make sure that the @display_info, @width_mm and @height_mm fields of the |
675 | * struct #drm_connector are filled in. | 675 | * struct &drm_connector are filled in. |
676 | * | 676 | * |
677 | * Virtual drivers that just want some standard VESA mode with a given | 677 | * Virtual drivers that just want some standard VESA mode with a given |
678 | * resolution can call drm_add_modes_noedid(), and mark the preferred | 678 | * resolution can call drm_add_modes_noedid(), and mark the preferred |
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 13ff44b28893..220d1e2b3db1 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h | |||
@@ -75,6 +75,14 @@ struct drm_panel_funcs { | |||
75 | struct display_timing *timings); | 75 | struct display_timing *timings); |
76 | }; | 76 | }; |
77 | 77 | ||
78 | /** | ||
79 | * struct drm_panel - DRM panel object | ||
80 | * @drm: DRM device owning the panel | ||
81 | * @connector: DRM connector that the panel is attached to | ||
82 | * @dev: parent device of the panel | ||
83 | * @funcs: operations that can be performed on the panel | ||
84 | * @list: panel entry in registry | ||
85 | */ | ||
78 | struct drm_panel { | 86 | struct drm_panel { |
79 | struct drm_device *drm; | 87 | struct drm_device *drm; |
80 | struct drm_connector *connector; | 88 | struct drm_connector *connector; |
@@ -85,6 +93,17 @@ struct drm_panel { | |||
85 | struct list_head list; | 93 | struct list_head list; |
86 | }; | 94 | }; |
87 | 95 | ||
96 | /** | ||
97 | * drm_disable_unprepare - power off a panel | ||
98 | * @panel: DRM panel | ||
99 | * | ||
100 | * Calling this function will completely power off a panel (assert the panel's | ||
101 | * reset, turn off power supplies, ...). After this function has completed, it | ||
102 | * is usually no longer possible to communicate with the panel until another | ||
103 | * call to drm_panel_prepare(). | ||
104 | * | ||
105 | * Return: 0 on success or a negative error code on failure. | ||
106 | */ | ||
88 | static inline int drm_panel_unprepare(struct drm_panel *panel) | 107 | static inline int drm_panel_unprepare(struct drm_panel *panel) |
89 | { | 108 | { |
90 | if (panel && panel->funcs && panel->funcs->unprepare) | 109 | if (panel && panel->funcs && panel->funcs->unprepare) |
@@ -93,6 +112,16 @@ static inline int drm_panel_unprepare(struct drm_panel *panel) | |||
93 | return panel ? -ENOSYS : -EINVAL; | 112 | return panel ? -ENOSYS : -EINVAL; |
94 | } | 113 | } |
95 | 114 | ||
115 | /** | ||
116 | * drm_panel_disable - disable a panel | ||
117 | * @panel: DRM panel | ||
118 | * | ||
119 | * This will typically turn off the panel's backlight or disable the display | ||
120 | * drivers. For smart panels it should still be possible to communicate with | ||
121 | * the integrated circuitry via any command bus after this call. | ||
122 | * | ||
123 | * Return: 0 on success or a negative error code on failure. | ||
124 | */ | ||
96 | static inline int drm_panel_disable(struct drm_panel *panel) | 125 | static inline int drm_panel_disable(struct drm_panel *panel) |
97 | { | 126 | { |
98 | if (panel && panel->funcs && panel->funcs->disable) | 127 | if (panel && panel->funcs && panel->funcs->disable) |
@@ -101,6 +130,16 @@ static inline int drm_panel_disable(struct drm_panel *panel) | |||
101 | return panel ? -ENOSYS : -EINVAL; | 130 | return panel ? -ENOSYS : -EINVAL; |
102 | } | 131 | } |
103 | 132 | ||
133 | /** | ||
134 | * drm_panel_prepare - power on a panel | ||
135 | * @panel: DRM panel | ||
136 | * | ||
137 | * Calling this function will enable power and deassert any reset signals to | ||
138 | * the panel. After this has completed it is possible to communicate with any | ||
139 | * integrated circuitry via a command bus. | ||
140 | * | ||
141 | * Return: 0 on success or a negative error code on failure. | ||
142 | */ | ||
104 | static inline int drm_panel_prepare(struct drm_panel *panel) | 143 | static inline int drm_panel_prepare(struct drm_panel *panel) |
105 | { | 144 | { |
106 | if (panel && panel->funcs && panel->funcs->prepare) | 145 | if (panel && panel->funcs && panel->funcs->prepare) |
@@ -109,6 +148,16 @@ static inline int drm_panel_prepare(struct drm_panel *panel) | |||
109 | return panel ? -ENOSYS : -EINVAL; | 148 | return panel ? -ENOSYS : -EINVAL; |
110 | } | 149 | } |
111 | 150 | ||
151 | /** | ||
152 | * drm_panel_enable - enable a panel | ||
153 | * @panel: DRM panel | ||
154 | * | ||
155 | * Calling this function will cause the panel display drivers to be turned on | ||
156 | * and the backlight to be enabled. Content will be visible on screen after | ||
157 | * this call completes. | ||
158 | * | ||
159 | * Return: 0 on success or a negative error code on failure. | ||
160 | */ | ||
112 | static inline int drm_panel_enable(struct drm_panel *panel) | 161 | static inline int drm_panel_enable(struct drm_panel *panel) |
113 | { | 162 | { |
114 | if (panel && panel->funcs && panel->funcs->enable) | 163 | if (panel && panel->funcs && panel->funcs->enable) |
@@ -117,6 +166,16 @@ static inline int drm_panel_enable(struct drm_panel *panel) | |||
117 | return panel ? -ENOSYS : -EINVAL; | 166 | return panel ? -ENOSYS : -EINVAL; |
118 | } | 167 | } |
119 | 168 | ||
169 | /** | ||
170 | * drm_panel_get_modes - probe the available display modes of a panel | ||
171 | * @panel: DRM panel | ||
172 | * | ||
173 | * The modes probed from the panel are automatically added to the connector | ||
174 | * that the panel is attached to. | ||
175 | * | ||
176 | * Return: The number of modes available from the panel on success or a | ||
177 | * negative error code on failure. | ||
178 | */ | ||
120 | static inline int drm_panel_get_modes(struct drm_panel *panel) | 179 | static inline int drm_panel_get_modes(struct drm_panel *panel) |
121 | { | 180 | { |
122 | if (panel && panel->funcs && panel->funcs->get_modes) | 181 | if (panel && panel->funcs && panel->funcs->get_modes) |