@@ -134,6 +134,9 @@ void drm_panel_prepare(struct drm_panel *panel)
134134 panel -> prepared = true;
135135
136136 list_for_each_entry (follower , & panel -> followers , list ) {
137+ if (!follower -> funcs -> panel_prepared )
138+ continue ;
139+
137140 ret = follower -> funcs -> panel_prepared (follower );
138141 if (ret < 0 )
139142 dev_info (panel -> dev , "%ps failed: %d\n" ,
@@ -179,6 +182,9 @@ void drm_panel_unprepare(struct drm_panel *panel)
179182 mutex_lock (& panel -> follower_lock );
180183
181184 list_for_each_entry (follower , & panel -> followers , list ) {
185+ if (!follower -> funcs -> panel_unpreparing )
186+ continue ;
187+
182188 ret = follower -> funcs -> panel_unpreparing (follower );
183189 if (ret < 0 )
184190 dev_info (panel -> dev , "%ps failed: %d\n" ,
@@ -209,6 +215,7 @@ EXPORT_SYMBOL(drm_panel_unprepare);
209215 */
210216void drm_panel_enable (struct drm_panel * panel )
211217{
218+ struct drm_panel_follower * follower ;
212219 int ret ;
213220
214221 if (!panel )
@@ -219,17 +226,32 @@ void drm_panel_enable(struct drm_panel *panel)
219226 return ;
220227 }
221228
229+ mutex_lock (& panel -> follower_lock );
230+
222231 if (panel -> funcs && panel -> funcs -> enable ) {
223232 ret = panel -> funcs -> enable (panel );
224233 if (ret < 0 )
225- return ;
234+ goto exit ;
226235 }
227236 panel -> enabled = true;
228237
229238 ret = backlight_enable (panel -> backlight );
230239 if (ret < 0 )
231240 DRM_DEV_INFO (panel -> dev , "failed to enable backlight: %d\n" ,
232241 ret );
242+
243+ list_for_each_entry (follower , & panel -> followers , list ) {
244+ if (!follower -> funcs -> panel_enabled )
245+ continue ;
246+
247+ ret = follower -> funcs -> panel_enabled (follower );
248+ if (ret < 0 )
249+ dev_info (panel -> dev , "%ps failed: %d\n" ,
250+ follower -> funcs -> panel_enabled , ret );
251+ }
252+
253+ exit :
254+ mutex_unlock (& panel -> follower_lock );
233255}
234256EXPORT_SYMBOL (drm_panel_enable );
235257
@@ -243,6 +265,7 @@ EXPORT_SYMBOL(drm_panel_enable);
243265 */
244266void drm_panel_disable (struct drm_panel * panel )
245267{
268+ struct drm_panel_follower * follower ;
246269 int ret ;
247270
248271 if (!panel )
@@ -262,6 +285,18 @@ void drm_panel_disable(struct drm_panel *panel)
262285 return ;
263286 }
264287
288+ mutex_lock (& panel -> follower_lock );
289+
290+ list_for_each_entry (follower , & panel -> followers , list ) {
291+ if (!follower -> funcs -> panel_disabling )
292+ continue ;
293+
294+ ret = follower -> funcs -> panel_disabling (follower );
295+ if (ret < 0 )
296+ dev_info (panel -> dev , "%ps failed: %d\n" ,
297+ follower -> funcs -> panel_disabling , ret );
298+ }
299+
265300 ret = backlight_disable (panel -> backlight );
266301 if (ret < 0 )
267302 DRM_DEV_INFO (panel -> dev , "failed to disable backlight: %d\n" ,
@@ -270,9 +305,12 @@ void drm_panel_disable(struct drm_panel *panel)
270305 if (panel -> funcs && panel -> funcs -> disable ) {
271306 ret = panel -> funcs -> disable (panel );
272307 if (ret < 0 )
273- return ;
308+ goto exit ;
274309 }
275310 panel -> enabled = false;
311+
312+ exit :
313+ mutex_unlock (& panel -> follower_lock );
276314}
277315EXPORT_SYMBOL (drm_panel_disable );
278316
@@ -539,13 +577,13 @@ EXPORT_SYMBOL(drm_is_panel_follower);
539577 * @follower_dev: The 'struct device' for the follower.
540578 * @follower: The panel follower descriptor for the follower.
541579 *
542- * A panel follower is called right after preparing the panel and right before
543- * unpreparing the panel. It's primary intention is to power on an associated
544- * touchscreen, though it could be used for any similar devices. Multiple
545- * devices are allowed the follow the same panel.
580+ * A panel follower is called right after preparing/enabling the panel and right
581+ * before unpreparing/disabling the panel. It's primary intention is to power on
582+ * an associated touchscreen, though it could be used for any similar devices.
583+ * Multiple devices are allowed the follow the same panel.
546584 *
547- * If a follower is added to a panel that's already been turned on , the
548- * follower's prepare callback is called right away.
585+ * If a follower is added to a panel that's already been prepared/enabled , the
586+ * follower's prepared/enabled callback is called right away.
549587 *
550588 * The "panel" property of the follower points to the panel to be followed.
551589 *
@@ -569,12 +607,18 @@ int drm_panel_add_follower(struct device *follower_dev,
569607 mutex_lock (& panel -> follower_lock );
570608
571609 list_add_tail (& follower -> list , & panel -> followers );
572- if (panel -> prepared ) {
610+ if (panel -> prepared && follower -> funcs -> panel_prepared ) {
573611 ret = follower -> funcs -> panel_prepared (follower );
574612 if (ret < 0 )
575613 dev_info (panel -> dev , "%ps failed: %d\n" ,
576614 follower -> funcs -> panel_prepared , ret );
577615 }
616+ if (panel -> enabled && follower -> funcs -> panel_enabled ) {
617+ ret = follower -> funcs -> panel_enabled (follower );
618+ if (ret < 0 )
619+ dev_info (panel -> dev , "%ps failed: %d\n" ,
620+ follower -> funcs -> panel_enabled , ret );
621+ }
578622
579623 mutex_unlock (& panel -> follower_lock );
580624
@@ -587,7 +631,8 @@ EXPORT_SYMBOL(drm_panel_add_follower);
587631 * @follower: The panel follower descriptor for the follower.
588632 *
589633 * Undo drm_panel_add_follower(). This includes calling the follower's
590- * unprepare function if we're removed from a panel that's currently prepared.
634+ * unpreparing/disabling function if we're removed from a panel that's currently
635+ * prepared/enabled.
591636 *
592637 * Return: 0 or an error code.
593638 */
@@ -598,7 +643,13 @@ void drm_panel_remove_follower(struct drm_panel_follower *follower)
598643
599644 mutex_lock (& panel -> follower_lock );
600645
601- if (panel -> prepared ) {
646+ if (panel -> enabled && follower -> funcs -> panel_disabling ) {
647+ ret = follower -> funcs -> panel_disabling (follower );
648+ if (ret < 0 )
649+ dev_info (panel -> dev , "%ps failed: %d\n" ,
650+ follower -> funcs -> panel_disabling , ret );
651+ }
652+ if (panel -> prepared && follower -> funcs -> panel_unpreparing ) {
602653 ret = follower -> funcs -> panel_unpreparing (follower );
603654 if (ret < 0 )
604655 dev_info (panel -> dev , "%ps failed: %d\n" ,
0 commit comments