[PATCH 01/10] drm/panel: Keep track of enabled/prepared

Andrzej Hajda a.hajda at samsung.com
Fri Sep 22 07:22:55 UTC 2017


On 22.09.2017 09:13, Andrzej Hajda wrote:
> On 21.09.2017 19:06, Sean Paul wrote:
>> This patch adds state tracking to the drm_panel functions which keep
>> track of enabled and prepared. If the calls are unbalanced, a WARNING is
>> issued.
>>
>> The motivation for this change is that a number of panel drivers
>> (including panel-simple) all do this to protect their regulator
>> refcounts. The atomic framework ensures the calls are balanced, and
>> there  aren't any panel drivers being used by legacy drivers. As such,
>> these checks are useless, but let's add a WARNING just in case something
>> crazy happens (like a legacy driver using a panel).
>>
>> Less code == better.
>>
>> Signed-off-by: Sean Paul <seanpaul at chromium.org>
> I wonder if the tracking is needed at all, panels power states are
> usually the same as states of encoders they are connected to.
> But it is just remark to consider, no strong opposition :)
>
>> ---
>>  drivers/gpu/drm/drm_panel.c |  2 ++
>>  include/drm/drm_panel.h     | 38 ++++++++++++++++++++++++++++++++++----
>>  2 files changed, 36 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
>> index 308d442a531b..9515219d3d2c 100644
>> --- a/drivers/gpu/drm/drm_panel.c
>> +++ b/drivers/gpu/drm/drm_panel.c
>> @@ -48,6 +48,8 @@ static LIST_HEAD(panel_list);
>>  void drm_panel_init(struct drm_panel *panel)
>>  {
>>  	INIT_LIST_HEAD(&panel->list);
>> +	panel->enabled = false;
>> +	panel->prepared = false;
>>  }
>>  EXPORT_SYMBOL(drm_panel_init);
>>  
>> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
>> index 14ac240a1f64..b9a86a4cf29c 100644
>> --- a/include/drm/drm_panel.h
>> +++ b/include/drm/drm_panel.h
>> @@ -24,6 +24,7 @@
>>  #ifndef __DRM_PANEL_H__
>>  #define __DRM_PANEL_H__
>>  
>> +#include <linux/bug.h>
>>  #include <linux/errno.h>
>>  #include <linux/list.h>
>>  
>> @@ -84,6 +85,8 @@ struct drm_panel_funcs {
>>   * @dev: parent device of the panel
>>   * @funcs: operations that can be performed on the panel
>>   * @list: panel entry in registry
>> + * @enabled: keeps track of the panel enabled status
>> + * @prepared: keeps track of the panel prepared status
>>   */
>>  struct drm_panel {
>>  	struct drm_device *drm;
>> @@ -93,6 +96,9 @@ struct drm_panel {
>>  	const struct drm_panel_funcs *funcs;
>>  
>>  	struct list_head list;
>> +
>> +	bool enabled;
>> +	bool prepared;

I think better would be to use enum {disabled, prepared, enabled} here,
the checks will be more readable, and will fit better to panel state
machine :), just to consider.

Regards
Andrzej

>>  };
>>  
>>  /**
>> @@ -104,12 +110,18 @@ struct drm_panel {
>>   * is usually no longer possible to communicate with the panel until another
>>   * call to drm_panel_prepare().
>>   *
>> + * Atomic framework should ensure that prepare/unprepare are properly balanced.
>> + * If this is not the case, a WARNING will be issued.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  static inline int drm_panel_unprepare(struct drm_panel *panel)
>>  {
>> -	if (panel && panel->funcs && panel->funcs->unprepare)
>> +	if (panel && panel->funcs && panel->funcs->unprepare) {
>> +		WARN_ON(!panel->prepared);
> WARN_ON(!panel->prepared || panel->enabled);
>
> Similar double checks should be used in other places.
>
>> +		panel->prepared = false;
>>  		return panel->funcs->unprepare(panel);
> ret = panel->funcs->unprepare(panel);
> if (!ret)
>     panel->prepared = false;
> return ret;
>
> Again this pattern should be repeated in other places.
>
> Different thing is meaning of unsuccessful unprepare/disable? But this
> is other issue.
>
>> +	}
>>  
>>  	return panel ? -ENOSYS : -EINVAL;
> I think tracking should be performed also for no-op case.
>
> Regards
> Andrzej
>
>>  }
>> @@ -122,12 +134,18 @@ static inline int drm_panel_unprepare(struct drm_panel *panel)
>>   * drivers. For smart panels it should still be possible to communicate with
>>   * the integrated circuitry via any command bus after this call.
>>   *
>> + * Atomic framework should ensure that enable/disable are properly balanced.
>> + * If this is not the case, a WARNING will be issued.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  static inline int drm_panel_disable(struct drm_panel *panel)
>>  {
>> -	if (panel && panel->funcs && panel->funcs->disable)
>> +	if (panel && panel->funcs && panel->funcs->disable) {
>> +		WARN_ON(!panel->enabled);
>> +		panel->enabled = false;
>>  		return panel->funcs->disable(panel);
>> +	}
>>  
>>  	return panel ? -ENOSYS : -EINVAL;
>>  }
>> @@ -140,12 +158,18 @@ static inline int drm_panel_disable(struct drm_panel *panel)
>>   * the panel. After this has completed it is possible to communicate with any
>>   * integrated circuitry via a command bus.
>>   *
>> + * Atomic framework should ensure that prepare/unprepare are properly balanced.
>> + * If this is not the case, a WARNING will be issued.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  static inline int drm_panel_prepare(struct drm_panel *panel)
>>  {
>> -	if (panel && panel->funcs && panel->funcs->prepare)
>> +	if (panel && panel->funcs && panel->funcs->prepare) {
>> +		WARN_ON(panel->prepared);
>> +		panel->prepared = true;
>>  		return panel->funcs->prepare(panel);
>> +	}
>>  
>>  	return panel ? -ENOSYS : -EINVAL;
>>  }
>> @@ -158,12 +182,18 @@ static inline int drm_panel_prepare(struct drm_panel *panel)
>>   * and the backlight to be enabled. Content will be visible on screen after
>>   * this call completes.
>>   *
>> + * Atomic framework should ensure that enable/disable are properly balanced.
>> + * If this is not the case, a WARNING will be issued.
>> + *
>>   * Return: 0 on success or a negative error code on failure.
>>   */
>>  static inline int drm_panel_enable(struct drm_panel *panel)
>>  {
>> -	if (panel && panel->funcs && panel->funcs->enable)
>> +	if (panel && panel->funcs && panel->funcs->enable) {
>> +		WARN_ON(panel->enabled);
>> +		panel->enabled = true;
>>  		return panel->funcs->enable(panel);
>> +	}
>>  
>>  	return panel ? -ENOSYS : -EINVAL;
>>  }
>



More information about the dri-devel mailing list