[PATCH] drm/panel: Flesh out kerneldoc

Daniel Vetter daniel at ffwll.ch
Wed Nov 5 04:55:08 PST 2014


On Tue, Nov 04, 2014 at 05:26:13PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
> 
> Write more complete kerneldoc comments for the DRM panel API and
> integrate the helpers in the DRM DocBook reference.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>

A few comments below. With thos addressed this is

Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>

And feel free the ignore the bikeshed one of course ;-)

Cheers, Daniel

> ---
>  Documentation/DocBook/drm.tmpl |  6 +++++
>  drivers/gpu/drm/drm_panel.c    | 61 ++++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_panel.h        | 59 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 126 insertions(+)
> 
> diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
> index d89ca5830697..8737f03d9a75 100644
> --- a/Documentation/DocBook/drm.tmpl
> +++ b/Documentation/DocBook/drm.tmpl
> @@ -2379,6 +2379,12 @@ void intel_crt_init(struct drm_device *dev)
>        <title id="drm-kms-planehelpers">Plane Helper Reference</title>
>  !Edrivers/gpu/drm/drm_plane_helper.c Plane Helpers
>      </sect2>
> +    <sect2>
> +      <title>Panel Helper Reference</title>
> +!Iinclude/drm/drm_panel.h
> +!Edrivers/gpu/drm/drm_panel.c
> +!Pdrivers/gpu/drm/drm_panel.c drm panel
> +    </sect2>
>    </sect1>
>  
>    <!-- Internals: kms properties -->
> 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 @@
>  static DEFINE_MUTEX(panel_lock);
>  static LIST_HEAD(panel_list);
>  
> +/**
> + * DOC: drm panel
> + *
> + * The DRM panel helpers allow drivers to register panel objects with a
> + * central registry and provide functions to retrieve those panels in display
> + * drivers.

I think a few more words here would be useful.

"The goal is to be able to abstract away panel specific quirks and then
share panel drivers between different display drivers.""

> + */
> +
> +/**
> + * drm_panel_init - initialize a panel
> + * @panel: DRM panel
> + *
> + * Sets up internal fields of the panel so that it can subsequently be added
> + * to the registry.
> + */
>  void drm_panel_init(struct drm_panel *panel)
>  {
>  	INIT_LIST_HEAD(&panel->list);
>  }
>  EXPORT_SYMBOL(drm_panel_init);
>  
> +/**
> + * drm_panel_add - add a panel to the global registry
> + * @panel: panel to add
> + *
> + * Add a panel to the global registry so that it can be looked up by display
> + * drivers.
> + *
> + * Return: 0 on success or a negative error code on failure.

Bikeshed: I think the usual layout for return value sections in drm is

 * Returns:
 * blabla

i.e. with s at the end and newline before the blabla.

> + */
>  int drm_panel_add(struct drm_panel *panel)
>  {
>  	mutex_lock(&panel_lock);
> @@ -46,6 +70,12 @@ int drm_panel_add(struct drm_panel *panel)
>  }
>  EXPORT_SYMBOL(drm_panel_add);
>  
> +/**
> + * drm_panel_remove - remove a panel from the global registry
> + * @panel: DRM panel
> + *
> + * Removes a panel from the global registry.
> + */
>  void drm_panel_remove(struct drm_panel *panel)
>  {
>  	mutex_lock(&panel_lock);
> @@ -54,6 +84,18 @@ void drm_panel_remove(struct drm_panel *panel)
>  }
>  EXPORT_SYMBOL(drm_panel_remove);
>  
> +/**
> + * drm_panel_attach - attach a panel to a connector
> + * @panel: DRM panel
> + * @connector: DRM connector
> + *
> + * After obtaining a pointer to a DRM panel a display driver calls this
> + * function to attach a panel to a connector.
> + *
> + * An error is returned if the panel is already attached to another connector.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
>  int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
>  {
>  	if (panel->connector)
> @@ -66,6 +108,15 @@ int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
>  }
>  EXPORT_SYMBOL(drm_panel_attach);
>  
> +/**
> + * drm_panel_detach - detach a panel from a connector
> + * @panel: DRM panel
> + *
> + * Detaches a panel from the connector it is attached to. If a panel is not
> + * attached to any connector this is effectively a no-op.
> + *
> + * Return: 0 on success or a negative error code on failure.

This never fails. I think it's better to switch the return value to void
instead of documenting something that never actually happens. This kind of
interface polish is one of the main reasons I think doing kerneldoc is
useful

> + */
>  int drm_panel_detach(struct drm_panel *panel)
>  {
>  	panel->connector = NULL;
> @@ -76,6 +127,16 @@ int drm_panel_detach(struct drm_panel *panel)
>  EXPORT_SYMBOL(drm_panel_detach);
>  
>  #ifdef CONFIG_OF
> +/**
> + * of_drm_find_panel - look up a panel using a device tree node
> + * @np: device tree node of the panel
> + *
> + * Searches the set of registered panels for one that matches the given device
> + * tree node. If a matching panel is found, return a pointer to it.
> + *
> + * Return: A pointer to the panel registered for the specified device tree
> + * node or NULL if no panel matching the device tree node can be found.
> + */
>  struct drm_panel *of_drm_find_panel(struct device_node *np)
>  {
>  	struct drm_panel *panel;
> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> index 1fbcc96063a7..b88b4dcd698b 100644
> --- a/include/drm/drm_panel.h
> +++ b/include/drm/drm_panel.h
> @@ -70,6 +70,14 @@ struct drm_panel_funcs {
>  	int (*get_modes)(struct drm_panel *panel);
>  };
>  
> +/**
> + * struct drm_panel - DRM panel object
> + * @drm: DRM device owning the panel
> + * @connector: DRM connector that the panel is attached to
> + * @dev: parent device of the panel
> + * @funcs: operations that can be performed on the panel
> + * @list: panel entry in registry
> + */
>  struct drm_panel {
>  	struct drm_device *drm;
>  	struct drm_connector *connector;
> @@ -80,6 +88,17 @@ struct drm_panel {
>  	struct list_head list;
>  };
>  
> +/**
> + * drm_disable_unprepare - power off a panel
> + * @panel: DRM panel

I think all these static inline wrappers should start with something along
the lines of

"This function calls the ->foo() panel callback if provided."
> + *
> + * Calling this function will completely power off a panel (assert the panel's
> + * reset, turn off power supplies, ...). After this function has completed, it
> + * is usually no longer possible to communicate with the panel until another
> + * call to drm_panel_prepare().
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */

But thinking about the semantics of these functions I have a few
questions:
- panel seems to be optional, which doesn't make a lot of sense imo.
  Should we WARN_ON if it's not there.
- the vfuncs are all optional, which imo makes sense (I don't expect all
  panels to e.g. have a prepare). But if the vfunc isnt' there the
  function still fails. Usually no vfunc means silent success. But if it's
  an implementation error on the panel driver's side then I think there
  should be a WARN_ON both here and in the panel registration function.

>  static inline int drm_panel_unprepare(struct drm_panel *panel)
>  {
>  	if (panel && panel->funcs && panel->funcs->unprepare)
> @@ -88,6 +107,16 @@ static inline int drm_panel_unprepare(struct drm_panel *panel)
>  	return panel ? -ENOSYS : -EINVAL;
>  }
>  
> +/**
> + * drm_panel_disable - disable a panel
> + * @panel: DRM panel
> + *
> + * This will typically turn off the panel's backlight or disable the display
> + * drivers. For smart panels it should still be possible to communicate with
> + * the integrated circuitry via any command bus after this call.
> + *
> + * 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)
> @@ -96,6 +125,16 @@ static inline int drm_panel_disable(struct drm_panel *panel)
>  	return panel ? -ENOSYS : -EINVAL;
>  }
>  
> +/**
> + * drm_panel_prepare - power on a panel
> + * @panel: DRM panel
> + *
> + * Calling this function will enable power and deassert any reset signals to
> + * the panel. After this has completed it is possible to communicate with any
> + * integrated circuitry via a command bus.
> + *
> + * 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)
> @@ -104,6 +143,16 @@ static inline int drm_panel_prepare(struct drm_panel *panel)
>  	return panel ? -ENOSYS : -EINVAL;
>  }
>  
> +/**
> + * drm_panel_enable - enable a panel
> + * @panel: DRM panel
> + *
> + * Calling this function will cause the panel display drivers to be turned on
> + * and the backlight to be enabled. Content will be visible on screen after
> + * this call completes.
> + *
> + * 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)
> @@ -112,6 +161,16 @@ static inline int drm_panel_enable(struct drm_panel *panel)
>  	return panel ? -ENOSYS : -EINVAL;
>  }
>  
> +/**
> + * drm_panel_get_modes - probe the available display modes of a panel
> + * @panel: DRM panel
> + *
> + * The modes probed from the panel are automatically added to the connector
> + * that the panel is attached to.
> + *
> + * Return: The number of modes available from the panel on success or a
> + * negative error code on failure.
> + */
>  static inline int drm_panel_get_modes(struct drm_panel *panel)
>  {
>  	if (panel && panel->funcs && panel->funcs->get_modes)
> -- 
> 2.1.3
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch


More information about the dri-devel mailing list