diff mbox series

[2/6] drm: Add drm_simple_encoder_{init,create}()

Message ID 20200207084135.4524-3-tzimmermann@suse.de (mailing list archive)
State New, archived
Headers show
Series drm: Provide a simple encoder | expand

Commit Message

Thomas Zimmermann Feb. 7, 2020, 8:41 a.m. UTC
The simple-encoder helpers initialize an encoder with an empty
implementation. This covers the requirements of most of the existing
DRM drivers. A call to drm_simple_encoder_create() allocates and
initializes an encoder instance, a call to drm_simple_encoder_init()
initializes a pre-allocated instance.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_encoder.c | 116 ++++++++++++++++++++++++++++++++++
 include/drm/drm_encoder.h     |  10 +++
 2 files changed, 126 insertions(+)

Comments

Gerd Hoffmann Feb. 7, 2020, 10:33 a.m. UTC | #1
> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = {
> +	.destroy = drm_encoder_cleanup,
> +};
> +
> +/**
> + * drm_simple_encoder_init - Init a preallocated encoder
> + * @dev: drm device
> + * @funcs: callbacks for this encoder
> + * @encoder_type: user visible type of the encoder
> + * @name: printf style format string for the encoder name, or NULL
> + *        for default name
> + *
> + * Initialises a preallocated encoder that has no further functionality. The
> + * encoder will be released automatically.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drm_simple_encoder_init(struct drm_device *dev,
> +			    struct drm_encoder *encoder,
> +			    int encoder_type, const char *name, ...)

How about using

#define drm_simple_encoder_init(dev, type, name, ...) \
        drm_encoder_init(dev, drm_simple_encoder_funcs_cleanup, type, name, __VA_ARGS__)

instead ?

cheers,
  Gerd
Thomas Zimmermann Feb. 7, 2020, 10:50 a.m. UTC | #2
Hi Gerd

Am 07.02.20 um 11:33 schrieb Gerd Hoffmann:
>> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = {
>> +	.destroy = drm_encoder_cleanup,
>> +};
>> +
>> +/**
>> + * drm_simple_encoder_init - Init a preallocated encoder
>> + * @dev: drm device
>> + * @funcs: callbacks for this encoder
>> + * @encoder_type: user visible type of the encoder
>> + * @name: printf style format string for the encoder name, or NULL
>> + *        for default name
>> + *
>> + * Initialises a preallocated encoder that has no further functionality. The
>> + * encoder will be released automatically.
>> + *
>> + * Returns:
>> + * Zero on success, error code on failure.
>> + */
>> +int drm_simple_encoder_init(struct drm_device *dev,
>> +			    struct drm_encoder *encoder,
>> +			    int encoder_type, const char *name, ...)
> 
> How about using
> 
> #define drm_simple_encoder_init(dev, type, name, ...) \
>         drm_encoder_init(dev, drm_simple_encoder_funcs_cleanup, type, name, __VA_ARGS__)
> 
> instead ?

I'd prefer a function call for aesthetic reasons and for not having to
export the drm_simple_encoder_funcs_cleanup. drm_simple_encoder_create()
is also a function and probably cannot be turned into a macro. So having
a function for drm_simple_encoder_init seems consequent.

I guess you want to save a few lines in the implementation of
drm_simple_encoder_init() (?) If so, I'd rather try to share more
internal code among the various init and create functions.

Best regards
Thomas

> 
> cheers,
>   Gerd
>
Gerd Hoffmann Feb. 7, 2020, 12:31 p.m. UTC | #3
> > How about using
> > 
> > #define drm_simple_encoder_init(dev, type, name, ...) \
> >         drm_encoder_init(dev, drm_simple_encoder_funcs_cleanup, type, name, __VA_ARGS__)
> > 
> > instead ?

> I guess you want to save a few lines in the implementation of
> drm_simple_encoder_init() (?) If so, I'd rather try to share more
> internal code among the various init and create functions.

Yes.  You have the namestr stuff duplicated in all functions, and with
a #define that goes away.

But maybe that can be simply be dropped?  The drivers with a simple
encoder seem to not care much about the name and just pass NULL ...

cheers,
  Gerd
Daniel Vetter Feb. 7, 2020, 1:37 p.m. UTC | #4
On Fri, Feb 07, 2020 at 09:41:31AM +0100, Thomas Zimmermann wrote:
> The simple-encoder helpers initialize an encoder with an empty
> implementation. This covers the requirements of most of the existing
> DRM drivers. A call to drm_simple_encoder_create() allocates and
> initializes an encoder instance, a call to drm_simple_encoder_init()
> initializes a pre-allocated instance.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

This has quick a bit midlayer taste to it ... I think having this as a
helper would be cleaner ...

The other bit is drm_encoder->possible_crtcs. If we do create a helper for
these, lets at least try to make them not suck too badly :-) Otherwise I
guess it would be time to officially document what exactly possible_crtcs
== 0 means from an uabi pov.
-Daniel

> ---
>  drivers/gpu/drm/drm_encoder.c | 116 ++++++++++++++++++++++++++++++++++
>  include/drm/drm_encoder.h     |  10 +++
>  2 files changed, 126 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
> index ffe691a1bf34..1a65cab1f310 100644
> --- a/drivers/gpu/drm/drm_encoder.c
> +++ b/drivers/gpu/drm/drm_encoder.c
> @@ -178,6 +178,122 @@ int drm_encoder_init(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL(drm_encoder_init);
>  
> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = {
> +	.destroy = drm_encoder_cleanup,
> +};
> +
> +/**
> + * drm_simple_encoder_init - Init a preallocated encoder
> + * @dev: drm device
> + * @funcs: callbacks for this encoder
> + * @encoder_type: user visible type of the encoder
> + * @name: printf style format string for the encoder name, or NULL
> + *        for default name
> + *
> + * Initialises a preallocated encoder that has no further functionality. The
> + * encoder will be released automatically.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drm_simple_encoder_init(struct drm_device *dev,
> +			    struct drm_encoder *encoder,
> +			    int encoder_type, const char *name, ...)
> +{
> +	char *namestr = NULL;
> +	int ret;
> +
> +	if (name) {
> +		va_list ap;
> +
> +		va_start(ap, name);
> +		namestr = kvasprintf(GFP_KERNEL, name, ap);
> +		va_end(ap);
> +		if (!namestr)
> +			return -ENOMEM;
> +	}
> +
> +	ret = __drm_encoder_init(dev, encoder,
> +				 &drm_simple_encoder_funcs_cleanup,
> +				 encoder_type, namestr);
> +	if (ret)
> +		goto err_kfree;
> +
> +	return 0;
> +
> +err_kfree:
> +	if (name)
> +		kfree(namestr);
> +	return ret;
> +}
> +EXPORT_SYMBOL(drm_simple_encoder_init);
> +
> +static void drm_encoder_destroy(struct drm_encoder *encoder)
> +{
> +	struct drm_device *dev = encoder->dev;
> +
> +	drm_encoder_cleanup(encoder);
> +	devm_kfree(dev->dev, encoder);
> +}
> +
> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_destroy = {
> +	.destroy = drm_encoder_destroy,
> +};
> +
> +/**
> + * drm_simple_encoder_create - Allocate and initialize an encoder
> + * @dev: drm device
> + * @encoder_type: user visible type of the encoder
> + * @name: printf style format string for the encoder name, or NULL for
> + *        default name
> + *
> + * Allocates and initialises an encoder that has no further functionality. The
> + * encoder will be released automatically.
> + *
> + * Returns:
> + * The encoder on success, a pointer-encoder error code on failure.
> + */
> +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
> +					      int encoder_type,
> +					      const char *name, ...)
> +{
> +	char *namestr = NULL;
> +	struct drm_encoder *encoder;
> +	int ret;
> +
> +	encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
> +	if (!encoder)
> +		return ERR_PTR(-ENOMEM);
> +
> +	if (name) {
> +		va_list ap;
> +
> +		va_start(ap, name);
> +		namestr = kvasprintf(GFP_KERNEL, name, ap);
> +		va_end(ap);
> +		if (!namestr) {
> +			ret = -ENOMEM;
> +			goto err_devm_kfree;
> +		}
> +	}
> +
> +	ret = __drm_encoder_init(dev, encoder,
> +				 &drm_simple_encoder_funcs_destroy,
> +				 encoder_type, namestr);
> +	if (ret)
> +		goto err_kfree;
> +
> +	return encoder;
> +
> +err_kfree:
> +	if (name)
> +		kfree(namestr);
> +err_devm_kfree:
> +	devm_kfree(dev->dev, encoder);
> +	return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL(drm_simple_encoder_create);
> +
>  /**
>   * drm_encoder_cleanup - cleans up an initialised encoder
>   * @encoder: encoder to cleanup
> diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
> index 5623994b6e9e..0214f6cf9de6 100644
> --- a/include/drm/drm_encoder.h
> +++ b/include/drm/drm_encoder.h
> @@ -190,6 +190,16 @@ int drm_encoder_init(struct drm_device *dev,
>  		     const struct drm_encoder_funcs *funcs,
>  		     int encoder_type, const char *name, ...);
>  
> +__printf(4, 5)
> +int drm_simple_encoder_init(struct drm_device *dev,
> +			    struct drm_encoder *encoder,
> +			    int encoder_type, const char *name, ...);
> +
> +__printf(3, 4)
> +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
> +					      int encoder_type,
> +					      const char *name, ...);
> +
>  /**
>   * drm_encoder_index - find the index of a registered encoder
>   * @encoder: encoder to find index for
> -- 
> 2.25.0
>
Ville Syrjälä Feb. 7, 2020, 2 p.m. UTC | #5
On Fri, Feb 07, 2020 at 02:37:20PM +0100, Daniel Vetter wrote:
> On Fri, Feb 07, 2020 at 09:41:31AM +0100, Thomas Zimmermann wrote:
> > The simple-encoder helpers initialize an encoder with an empty
> > implementation. This covers the requirements of most of the existing
> > DRM drivers. A call to drm_simple_encoder_create() allocates and
> > initializes an encoder instance, a call to drm_simple_encoder_init()
> > initializes a pre-allocated instance.
> > 
> > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> 
> This has quick a bit midlayer taste to it ... I think having this as a
> helper would be cleaner ...
> 
> The other bit is drm_encoder->possible_crtcs. If we do create a helper for
> these, lets at least try to make them not suck too badly :-) Otherwise I
> guess it would be time to officially document what exactly possible_crtcs
> == 0 means from an uabi pov.

I had some improvements for this stuff. Just re-sent the remainder.
Thomas Zimmermann Feb. 7, 2020, 2:02 p.m. UTC | #6
Hi

Am 07.02.20 um 14:37 schrieb Daniel Vetter:
> On Fri, Feb 07, 2020 at 09:41:31AM +0100, Thomas Zimmermann wrote:
>> The simple-encoder helpers initialize an encoder with an empty
>> implementation. This covers the requirements of most of the existing
>> DRM drivers. A call to drm_simple_encoder_create() allocates and
>> initializes an encoder instance, a call to drm_simple_encoder_init()
>> initializes a pre-allocated instance.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> 
> This has quick a bit midlayer taste to it ... I think having this as a
> helper would be cleaner ...

How would such a helper roughly look like?

Best regards
Thomas

> 
> The other bit is drm_encoder->possible_crtcs. If we do create a helper for
> these, lets at least try to make them not suck too badly :-) Otherwise I
> guess it would be time to officially document what exactly possible_crtcs
> == 0 means from an uabi pov.
> -Daniel
> 
>> ---
>>  drivers/gpu/drm/drm_encoder.c | 116 ++++++++++++++++++++++++++++++++++
>>  include/drm/drm_encoder.h     |  10 +++
>>  2 files changed, 126 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
>> index ffe691a1bf34..1a65cab1f310 100644
>> --- a/drivers/gpu/drm/drm_encoder.c
>> +++ b/drivers/gpu/drm/drm_encoder.c
>> @@ -178,6 +178,122 @@ int drm_encoder_init(struct drm_device *dev,
>>  }
>>  EXPORT_SYMBOL(drm_encoder_init);
>>  
>> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = {
>> +	.destroy = drm_encoder_cleanup,
>> +};
>> +
>> +/**
>> + * drm_simple_encoder_init - Init a preallocated encoder
>> + * @dev: drm device
>> + * @funcs: callbacks for this encoder
>> + * @encoder_type: user visible type of the encoder
>> + * @name: printf style format string for the encoder name, or NULL
>> + *        for default name
>> + *
>> + * Initialises a preallocated encoder that has no further functionality. The
>> + * encoder will be released automatically.
>> + *
>> + * Returns:
>> + * Zero on success, error code on failure.
>> + */
>> +int drm_simple_encoder_init(struct drm_device *dev,
>> +			    struct drm_encoder *encoder,
>> +			    int encoder_type, const char *name, ...)
>> +{
>> +	char *namestr = NULL;
>> +	int ret;
>> +
>> +	if (name) {
>> +		va_list ap;
>> +
>> +		va_start(ap, name);
>> +		namestr = kvasprintf(GFP_KERNEL, name, ap);
>> +		va_end(ap);
>> +		if (!namestr)
>> +			return -ENOMEM;
>> +	}
>> +
>> +	ret = __drm_encoder_init(dev, encoder,
>> +				 &drm_simple_encoder_funcs_cleanup,
>> +				 encoder_type, namestr);
>> +	if (ret)
>> +		goto err_kfree;
>> +
>> +	return 0;
>> +
>> +err_kfree:
>> +	if (name)
>> +		kfree(namestr);
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL(drm_simple_encoder_init);
>> +
>> +static void drm_encoder_destroy(struct drm_encoder *encoder)
>> +{
>> +	struct drm_device *dev = encoder->dev;
>> +
>> +	drm_encoder_cleanup(encoder);
>> +	devm_kfree(dev->dev, encoder);
>> +}
>> +
>> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_destroy = {
>> +	.destroy = drm_encoder_destroy,
>> +};
>> +
>> +/**
>> + * drm_simple_encoder_create - Allocate and initialize an encoder
>> + * @dev: drm device
>> + * @encoder_type: user visible type of the encoder
>> + * @name: printf style format string for the encoder name, or NULL for
>> + *        default name
>> + *
>> + * Allocates and initialises an encoder that has no further functionality. The
>> + * encoder will be released automatically.
>> + *
>> + * Returns:
>> + * The encoder on success, a pointer-encoder error code on failure.
>> + */
>> +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
>> +					      int encoder_type,
>> +					      const char *name, ...)
>> +{
>> +	char *namestr = NULL;
>> +	struct drm_encoder *encoder;
>> +	int ret;
>> +
>> +	encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
>> +	if (!encoder)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	if (name) {
>> +		va_list ap;
>> +
>> +		va_start(ap, name);
>> +		namestr = kvasprintf(GFP_KERNEL, name, ap);
>> +		va_end(ap);
>> +		if (!namestr) {
>> +			ret = -ENOMEM;
>> +			goto err_devm_kfree;
>> +		}
>> +	}
>> +
>> +	ret = __drm_encoder_init(dev, encoder,
>> +				 &drm_simple_encoder_funcs_destroy,
>> +				 encoder_type, namestr);
>> +	if (ret)
>> +		goto err_kfree;
>> +
>> +	return encoder;
>> +
>> +err_kfree:
>> +	if (name)
>> +		kfree(namestr);
>> +err_devm_kfree:
>> +	devm_kfree(dev->dev, encoder);
>> +	return ERR_PTR(ret);
>> +}
>> +EXPORT_SYMBOL(drm_simple_encoder_create);
>> +
>>  /**
>>   * drm_encoder_cleanup - cleans up an initialised encoder
>>   * @encoder: encoder to cleanup
>> diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
>> index 5623994b6e9e..0214f6cf9de6 100644
>> --- a/include/drm/drm_encoder.h
>> +++ b/include/drm/drm_encoder.h
>> @@ -190,6 +190,16 @@ int drm_encoder_init(struct drm_device *dev,
>>  		     const struct drm_encoder_funcs *funcs,
>>  		     int encoder_type, const char *name, ...);
>>  
>> +__printf(4, 5)
>> +int drm_simple_encoder_init(struct drm_device *dev,
>> +			    struct drm_encoder *encoder,
>> +			    int encoder_type, const char *name, ...);
>> +
>> +__printf(3, 4)
>> +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
>> +					      int encoder_type,
>> +					      const char *name, ...);
>> +
>>  /**
>>   * drm_encoder_index - find the index of a registered encoder
>>   * @encoder: encoder to find index for
>> -- 
>> 2.25.0
>>
>
Noralf Trønnes Feb. 7, 2020, 2:36 p.m. UTC | #7
Den 07.02.2020 09.41, skrev Thomas Zimmermann:
> The simple-encoder helpers initialize an encoder with an empty
> implementation. This covers the requirements of most of the existing
> DRM drivers. A call to drm_simple_encoder_create() allocates and
> initializes an encoder instance, a call to drm_simple_encoder_init()
> initializes a pre-allocated instance.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
>  drivers/gpu/drm/drm_encoder.c | 116 ++++++++++++++++++++++++++++++++++
>  include/drm/drm_encoder.h     |  10 +++
>  2 files changed, 126 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c

<snip>

> +/**
> + * drm_simple_encoder_create - Allocate and initialize an encoder
> + * @dev: drm device
> + * @encoder_type: user visible type of the encoder
> + * @name: printf style format string for the encoder name, or NULL for
> + *        default name
> + *
> + * Allocates and initialises an encoder that has no further functionality. The
> + * encoder will be released automatically.
> + *
> + * Returns:
> + * The encoder on success, a pointer-encoder error code on failure.
> + */
> +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
> +					      int encoder_type,
> +					      const char *name, ...)
> +{
> +	char *namestr = NULL;
> +	struct drm_encoder *encoder;
> +	int ret;
> +
> +	encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);

The encoder can outlive the devres if the device is unbound when
userspace has open fds, so you can't use devm_ here.

Noralf.

> +	if (!encoder)
> +		return ERR_PTR(-ENOMEM);
> +
> +	if (name) {
> +		va_list ap;
> +
> +		va_start(ap, name);
> +		namestr = kvasprintf(GFP_KERNEL, name, ap);
> +		va_end(ap);
> +		if (!namestr) {
> +			ret = -ENOMEM;
> +			goto err_devm_kfree;
> +		}
> +	}
> +
> +	ret = __drm_encoder_init(dev, encoder,
> +				 &drm_simple_encoder_funcs_destroy,
> +				 encoder_type, namestr);
> +	if (ret)
> +		goto err_kfree;
> +
> +	return encoder;
> +
> +err_kfree:
> +	if (name)
> +		kfree(namestr);
> +err_devm_kfree:
> +	devm_kfree(dev->dev, encoder);
> +	return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL(drm_simple_encoder_create);
> +
Daniel Vetter Feb. 7, 2020, 4:25 p.m. UTC | #8
On Fri, Feb 07, 2020 at 03:36:49PM +0100, Noralf Trønnes wrote:
> 
> 
> Den 07.02.2020 09.41, skrev Thomas Zimmermann:
> > The simple-encoder helpers initialize an encoder with an empty
> > implementation. This covers the requirements of most of the existing
> > DRM drivers. A call to drm_simple_encoder_create() allocates and
> > initializes an encoder instance, a call to drm_simple_encoder_init()
> > initializes a pre-allocated instance.
> > 
> > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> > ---
> >  drivers/gpu/drm/drm_encoder.c | 116 ++++++++++++++++++++++++++++++++++
> >  include/drm/drm_encoder.h     |  10 +++
> >  2 files changed, 126 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
> 
> <snip>
> 
> > +/**
> > + * drm_simple_encoder_create - Allocate and initialize an encoder
> > + * @dev: drm device
> > + * @encoder_type: user visible type of the encoder
> > + * @name: printf style format string for the encoder name, or NULL for
> > + *        default name
> > + *
> > + * Allocates and initialises an encoder that has no further functionality. The
> > + * encoder will be released automatically.
> > + *
> > + * Returns:
> > + * The encoder on success, a pointer-encoder error code on failure.
> > + */
> > +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
> > +					      int encoder_type,
> > +					      const char *name, ...)
> > +{
> > +	char *namestr = NULL;
> > +	struct drm_encoder *encoder;
> > +	int ret;
> > +
> > +	encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
> 
> The encoder can outlive the devres if the device is unbound when
> userspace has open fds, so you can't use devm_ here.

Ah yes great catch. Rule of thumb: Never use devm_ for any drm_*
structure. It's wrong.

There's a todo somewhere to essentially create a drm_managed set of apis
where the cleanup matches the right lifetime - we need to only
free/release drm resource at drm_driver->release time.
-Daniel

> 
> Noralf.
> 
> > +	if (!encoder)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	if (name) {
> > +		va_list ap;
> > +
> > +		va_start(ap, name);
> > +		namestr = kvasprintf(GFP_KERNEL, name, ap);
> > +		va_end(ap);
> > +		if (!namestr) {
> > +			ret = -ENOMEM;
> > +			goto err_devm_kfree;
> > +		}
> > +	}
> > +
> > +	ret = __drm_encoder_init(dev, encoder,
> > +				 &drm_simple_encoder_funcs_destroy,
> > +				 encoder_type, namestr);
> > +	if (ret)
> > +		goto err_kfree;
> > +
> > +	return encoder;
> > +
> > +err_kfree:
> > +	if (name)
> > +		kfree(namestr);
> > +err_devm_kfree:
> > +	devm_kfree(dev->dev, encoder);
> > +	return ERR_PTR(ret);
> > +}
> > +EXPORT_SYMBOL(drm_simple_encoder_create);
> > +
Daniel Vetter Feb. 7, 2020, 4:26 p.m. UTC | #9
On Fri, Feb 07, 2020 at 03:02:00PM +0100, Thomas Zimmermann wrote:
> Hi
> 
> Am 07.02.20 um 14:37 schrieb Daniel Vetter:
> > On Fri, Feb 07, 2020 at 09:41:31AM +0100, Thomas Zimmermann wrote:
> >> The simple-encoder helpers initialize an encoder with an empty
> >> implementation. This covers the requirements of most of the existing
> >> DRM drivers. A call to drm_simple_encoder_create() allocates and
> >> initializes an encoder instance, a call to drm_simple_encoder_init()
> >> initializes a pre-allocated instance.
> >>
> >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> > 
> > This has quick a bit midlayer taste to it ... I think having this as a
> > helper would be cleaner ...
> 
> How would such a helper roughly look like?

Essentially same code, but stuff the helper into drm-kms-helper.ko, then
make sure it still works. The separate kernel module makes sure that the
drm core and helper stuff aren't too close friends with each another :-)
Essentially like the simple display pipe helpers.
-Daniel

> 
> Best regards
> Thomas
> 
> > 
> > The other bit is drm_encoder->possible_crtcs. If we do create a helper for
> > these, lets at least try to make them not suck too badly :-) Otherwise I
> > guess it would be time to officially document what exactly possible_crtcs
> > == 0 means from an uabi pov.
> > -Daniel
> > 
> >> ---
> >>  drivers/gpu/drm/drm_encoder.c | 116 ++++++++++++++++++++++++++++++++++
> >>  include/drm/drm_encoder.h     |  10 +++
> >>  2 files changed, 126 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
> >> index ffe691a1bf34..1a65cab1f310 100644
> >> --- a/drivers/gpu/drm/drm_encoder.c
> >> +++ b/drivers/gpu/drm/drm_encoder.c
> >> @@ -178,6 +178,122 @@ int drm_encoder_init(struct drm_device *dev,
> >>  }
> >>  EXPORT_SYMBOL(drm_encoder_init);
> >>  
> >> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = {
> >> +	.destroy = drm_encoder_cleanup,
> >> +};
> >> +
> >> +/**
> >> + * drm_simple_encoder_init - Init a preallocated encoder
> >> + * @dev: drm device
> >> + * @funcs: callbacks for this encoder
> >> + * @encoder_type: user visible type of the encoder
> >> + * @name: printf style format string for the encoder name, or NULL
> >> + *        for default name
> >> + *
> >> + * Initialises a preallocated encoder that has no further functionality. The
> >> + * encoder will be released automatically.
> >> + *
> >> + * Returns:
> >> + * Zero on success, error code on failure.
> >> + */
> >> +int drm_simple_encoder_init(struct drm_device *dev,
> >> +			    struct drm_encoder *encoder,
> >> +			    int encoder_type, const char *name, ...)
> >> +{
> >> +	char *namestr = NULL;
> >> +	int ret;
> >> +
> >> +	if (name) {
> >> +		va_list ap;
> >> +
> >> +		va_start(ap, name);
> >> +		namestr = kvasprintf(GFP_KERNEL, name, ap);
> >> +		va_end(ap);
> >> +		if (!namestr)
> >> +			return -ENOMEM;
> >> +	}
> >> +
> >> +	ret = __drm_encoder_init(dev, encoder,
> >> +				 &drm_simple_encoder_funcs_cleanup,
> >> +				 encoder_type, namestr);
> >> +	if (ret)
> >> +		goto err_kfree;
> >> +
> >> +	return 0;
> >> +
> >> +err_kfree:
> >> +	if (name)
> >> +		kfree(namestr);
> >> +	return ret;
> >> +}
> >> +EXPORT_SYMBOL(drm_simple_encoder_init);
> >> +
> >> +static void drm_encoder_destroy(struct drm_encoder *encoder)
> >> +{
> >> +	struct drm_device *dev = encoder->dev;
> >> +
> >> +	drm_encoder_cleanup(encoder);
> >> +	devm_kfree(dev->dev, encoder);
> >> +}
> >> +
> >> +static const struct drm_encoder_funcs drm_simple_encoder_funcs_destroy = {
> >> +	.destroy = drm_encoder_destroy,
> >> +};
> >> +
> >> +/**
> >> + * drm_simple_encoder_create - Allocate and initialize an encoder
> >> + * @dev: drm device
> >> + * @encoder_type: user visible type of the encoder
> >> + * @name: printf style format string for the encoder name, or NULL for
> >> + *        default name
> >> + *
> >> + * Allocates and initialises an encoder that has no further functionality. The
> >> + * encoder will be released automatically.
> >> + *
> >> + * Returns:
> >> + * The encoder on success, a pointer-encoder error code on failure.
> >> + */
> >> +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
> >> +					      int encoder_type,
> >> +					      const char *name, ...)
> >> +{
> >> +	char *namestr = NULL;
> >> +	struct drm_encoder *encoder;
> >> +	int ret;
> >> +
> >> +	encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
> >> +	if (!encoder)
> >> +		return ERR_PTR(-ENOMEM);
> >> +
> >> +	if (name) {
> >> +		va_list ap;
> >> +
> >> +		va_start(ap, name);
> >> +		namestr = kvasprintf(GFP_KERNEL, name, ap);
> >> +		va_end(ap);
> >> +		if (!namestr) {
> >> +			ret = -ENOMEM;
> >> +			goto err_devm_kfree;
> >> +		}
> >> +	}
> >> +
> >> +	ret = __drm_encoder_init(dev, encoder,
> >> +				 &drm_simple_encoder_funcs_destroy,
> >> +				 encoder_type, namestr);
> >> +	if (ret)
> >> +		goto err_kfree;
> >> +
> >> +	return encoder;
> >> +
> >> +err_kfree:
> >> +	if (name)
> >> +		kfree(namestr);
> >> +err_devm_kfree:
> >> +	devm_kfree(dev->dev, encoder);
> >> +	return ERR_PTR(ret);
> >> +}
> >> +EXPORT_SYMBOL(drm_simple_encoder_create);
> >> +
> >>  /**
> >>   * drm_encoder_cleanup - cleans up an initialised encoder
> >>   * @encoder: encoder to cleanup
> >> diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
> >> index 5623994b6e9e..0214f6cf9de6 100644
> >> --- a/include/drm/drm_encoder.h
> >> +++ b/include/drm/drm_encoder.h
> >> @@ -190,6 +190,16 @@ int drm_encoder_init(struct drm_device *dev,
> >>  		     const struct drm_encoder_funcs *funcs,
> >>  		     int encoder_type, const char *name, ...);
> >>  
> >> +__printf(4, 5)
> >> +int drm_simple_encoder_init(struct drm_device *dev,
> >> +			    struct drm_encoder *encoder,
> >> +			    int encoder_type, const char *name, ...);
> >> +
> >> +__printf(3, 4)
> >> +struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
> >> +					      int encoder_type,
> >> +					      const char *name, ...);
> >> +
> >>  /**
> >>   * drm_encoder_index - find the index of a registered encoder
> >>   * @encoder: encoder to find index for
> >> -- 
> >> 2.25.0
> >>
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
>
kernel test robot Feb. 10, 2020, 10:28 a.m. UTC | #10
Hi Thomas,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.6-rc1 next-20200210]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Thomas-Zimmermann/drm-Provide-a-simple-encoder/20200210-153139
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git bb6d3fb354c5ee8d6bde2d576eb7220ea09862b9
reproduce: make htmldocs

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'getprocattr' not described in 'security_list_options'
   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'setprocattr' not described in 'security_list_options'
   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'locked_down' not described in 'security_list_options'
   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'perf_event_open' not described in 'security_list_options'
   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'perf_event_alloc' not described in 'security_list_options'
   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'perf_event_free' not described in 'security_list_options'
   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'perf_event_read' not described in 'security_list_options'
   include/linux/lsm_hooks.h:1830: warning: Function parameter or member 'perf_event_write' not described in 'security_list_options'
   drivers/usb/typec/bus.c:1: warning: 'typec_altmode_register_driver' not found
   drivers/usb/typec/bus.c:1: warning: 'typec_altmode_unregister_driver' not found
   drivers/usb/typec/class.c:1: warning: 'typec_altmode_unregister_notifier' not found
   drivers/usb/typec/class.c:1: warning: 'typec_altmode_register_notifier' not found
   include/linux/regulator/machine.h:196: warning: Function parameter or member 'max_uV_step' not described in 'regulation_constraints'
   include/linux/regulator/driver.h:223: warning: Function parameter or member 'resume' not described in 'regulator_ops'
   include/linux/skbuff.h:890: warning: Function parameter or member 'dev_scratch' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'list' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'ip_defrag_offset' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'skb_mstamp_ns' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member '__cloned_offset' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'head_frag' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member '__pkt_type_offset' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'encapsulation' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'encap_hdr_csum' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'csum_valid' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member '__pkt_vlan_present_offset' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'vlan_present' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'csum_complete_sw' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'csum_level' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'inner_protocol_type' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'remcsum_offload' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'sender_cpu' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'reserved_tailroom' not described in 'sk_buff'
   include/linux/skbuff.h:890: warning: Function parameter or member 'inner_ipproto' not described in 'sk_buff'
   include/net/sock.h:232: warning: Function parameter or member 'skc_addrpair' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_portpair' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_ipv6only' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_net_refcnt' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_v6_daddr' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_v6_rcv_saddr' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_cookie' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_listener' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_tw_dr' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_rcv_wnd' not described in 'sock_common'
   include/net/sock.h:232: warning: Function parameter or member 'skc_tw_rcv_nxt' not described in 'sock_common'
   include/net/sock.h:498: warning: Function parameter or member 'sk_rx_skb_cache' not described in 'sock'
   include/net/sock.h:498: warning: Function parameter or member 'sk_wq_raw' not described in 'sock'
   include/net/sock.h:498: warning: Function parameter or member 'tcp_rtx_queue' not described in 'sock'
   include/net/sock.h:498: warning: Function parameter or member 'sk_tx_skb_cache' not described in 'sock'
   include/net/sock.h:498: warning: Function parameter or member 'sk_route_forced_caps' not described in 'sock'
   include/net/sock.h:498: warning: Function parameter or member 'sk_txtime_report_errors' not described in 'sock'
   include/net/sock.h:498: warning: Function parameter or member 'sk_validate_xmit_skb' not described in 'sock'
   include/net/sock.h:498: warning: Function parameter or member 'sk_bpf_storage' not described in 'sock'
   include/net/sock.h:2444: warning: Function parameter or member 'tcp_rx_skb_cache_key' not described in 'DECLARE_STATIC_KEY_FALSE'
   include/net/sock.h:2444: warning: Excess function parameter 'sk' description in 'DECLARE_STATIC_KEY_FALSE'
   include/net/sock.h:2444: warning: Excess function parameter 'skb' description in 'DECLARE_STATIC_KEY_FALSE'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'gso_partial_features' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'l3mdev_ops' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'xfrmdev_ops' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'tlsdev_ops' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'name_assign_type' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'ieee802154_ptr' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'mpls_ptr' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'xdp_prog' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'gro_flush_timeout' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'xdp_bulkq' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'xps_cpus_map' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'xps_rxqs_map' not described in 'net_device'
   include/linux/netdevice.h:2100: warning: Function parameter or member 'qdisc_hash' not described in 'net_device'
   include/linux/phylink.h:56: warning: Function parameter or member '__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising' not described in 'phylink_link_state'
   include/linux/phylink.h:56: warning: Function parameter or member '__ETHTOOL_DECLARE_LINK_MODE_MASK(lp_advertising' not described in 'phylink_link_state'
   drivers/infiniband/core/umem_odp.c:161: warning: Function parameter or member 'ops' not described in 'ib_umem_odp_alloc_child'
   drivers/infiniband/core/umem_odp.c:211: warning: Function parameter or member 'ops' not described in 'ib_umem_odp_get'
   drivers/infiniband/ulp/iser/iscsi_iser.h:401: warning: Function parameter or member 'all_list' not described in 'iser_fr_desc'
   drivers/infiniband/ulp/iser/iscsi_iser.h:415: warning: Function parameter or member 'all_list' not described in 'iser_fr_pool'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:148: warning: Function parameter or member 'rsvd0' not described in 'opa_vesw_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:148: warning: Function parameter or member 'rsvd1' not described in 'opa_vesw_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:148: warning: Function parameter or member 'rsvd2' not described in 'opa_vesw_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:148: warning: Function parameter or member 'rsvd3' not described in 'opa_vesw_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:148: warning: Function parameter or member 'rsvd4' not described in 'opa_vesw_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:205: warning: Function parameter or member 'rsvd0' not described in 'opa_per_veswport_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:205: warning: Function parameter or member 'rsvd1' not described in 'opa_per_veswport_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:205: warning: Function parameter or member 'rsvd2' not described in 'opa_per_veswport_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:205: warning: Function parameter or member 'rsvd3' not described in 'opa_per_veswport_info'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:263: warning: Function parameter or member 'tbl_entries' not described in 'opa_veswport_mactable'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:342: warning: Function parameter or member 'reserved' not described in 'opa_veswport_summary_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd0' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd1' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd2' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd3' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd4' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd5' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd6' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd7' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd8' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:394: warning: Function parameter or member 'rsvd9' not described in 'opa_veswport_error_counters'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:460: warning: Function parameter or member 'reserved' not described in 'opa_vnic_vema_mad'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:485: warning: Function parameter or member 'reserved' not described in 'opa_vnic_notice_attr'
   drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h:500: warning: Function parameter or member 'reserved' not described in 'opa_vnic_vema_mad_trap'
   include/linux/input/sparse-keymap.h:43: warning: Function parameter or member 'sw' not described in 'key_entry'
   drivers/gpu/drm/drm_encoder.c:202: warning: Excess function parameter 'funcs' description in 'drm_simple_encoder_init'
>> drivers/gpu/drm/drm_encoder.c:203: warning: Function parameter or member 'encoder' not described in 'drm_simple_encoder_init'
   drivers/gpu/drm/drm_encoder.c:203: warning: Excess function parameter 'funcs' description in 'drm_simple_encoder_init'
   include/drm/drm_modeset_helper_vtables.h:1052: warning: Function parameter or member 'prepare_writeback_job' not described in 'drm_connector_helper_funcs'
   include/drm/drm_modeset_helper_vtables.h:1052: warning: Function parameter or member 'cleanup_writeback_job' not described in 'drm_connector_helper_funcs'
   drivers/gpu/drm/bridge/panel.c:303: warning: Function parameter or member 'bridge' not described in 'drm_panel_bridge_connector'
   include/drm/drm_dp_mst_helper.h:162: warning: Function parameter or member 'fec_capable' not described in 'drm_dp_mst_port'
   include/drm/gpu_scheduler.h:103: warning: Function parameter or member 'priority' not described in 'drm_sched_entity'
   drivers/gpu/drm/i915/i915_vma.h:1: warning: 'Virtual Memory Address' not found
   drivers/gpu/drm/i915/i915_gem_gtt.c:1: warning: 'Global GTT views' not found
   include/linux/host1x.h:66: warning: Function parameter or member 'parent' not described in 'host1x_client'
   include/linux/host1x.h:66: warning: Function parameter or member 'usecount' not described in 'host1x_client'
   include/linux/host1x.h:66: warning: Function parameter or member 'lock' not described in 'host1x_client'
   include/net/cfg80211.h:1189: warning: Function parameter or member 'txpwr' not described in 'station_parameters'
   include/net/mac80211.h:4081: warning: Function parameter or member 'sta_set_txpwr' not described in 'ieee80211_ops'
   include/net/mac80211.h:2036: warning: Function parameter or member 'txpwr' not described in 'ieee80211_sta'
   kernel/sched/fair.c:3526: warning: Excess function parameter 'flags' description in 'attach_entity_load_avg'
   Documentation/admin-guide/acpi/fan_performance_states.rst:21: WARNING: Literal block ends without a blank line; unexpected unindent.
   Documentation/admin-guide/acpi/fan_performance_states.rst:41: WARNING: Literal block expected; none found.
   Documentation/admin-guide/perf/imx-ddr.rst:47: WARNING: Unexpected indentation.
   Documentation/x86/index.rst:7: WARNING: toctree contains reference to nonexisting document 'x86/intel_mpx'
   Documentation/admin-guide/bootconfig.rst:26: WARNING: Literal block expected; none found.
   Documentation/admin-guide/hw-vuln/tsx_async_abort.rst:142: WARNING: duplicate label virt_mechanism, other instance in Documentation/admin-guide/hw-vuln/mds.rst
   drivers/message/fusion/mptbase.c:5057: WARNING: Definition list ends without a blank line; unexpected unindent.
   include/uapi/linux/firewire-cdev.h:312: WARNING: Inline literal start-string without end-string.
   drivers/firewire/core-transaction.c:606: WARNING: Inline strong start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:425: WARNING: Unexpected indentation.
   Documentation/driver-api/gpio/driver.rst:423: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:427: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/gpio/driver.rst:429: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:429: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:429: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:433: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:446: WARNING: Unexpected indentation.
   Documentation/driver-api/gpio/driver.rst:440: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:440: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:447: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/gpio/driver.rst:449: WARNING: Definition list ends without a blank line; unexpected unindent.
   Documentation/driver-api/gpio/driver.rst:462: WARNING: Unexpected indentation.
   Documentation/driver-api/gpio/driver.rst:460: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:462: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:465: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/gpio/driver.rst:467: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:467: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:467: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:471: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/gpio/driver.rst:478: WARNING: Inline emphasis start-string without end-string.
   include/linux/spi/spi.h:399: WARNING: Unexpected indentation.
   Documentation/power/index.rst:7: WARNING: toctree contains reference to nonexisting document 'power/interface'
   Documentation/power/pm_qos_interface.rst:12: WARNING: Unexpected indentation.
   Documentation/admin-guide/ras.rst:358: WARNING: Definition list ends without a blank line; unexpected unindent.
   Documentation/admin-guide/ras.rst:358: WARNING: Definition list ends without a blank line; unexpected unindent.
   Documentation/admin-guide/ras.rst:363: WARNING: Definition list ends without a blank line; unexpected unindent.
   Documentation/admin-guide/ras.rst:363: WARNING: Definition list ends without a blank line; unexpected unindent.
   include/linux/devfreq.h:156: WARNING: Inline emphasis start-string without end-string.
   include/linux/devfreq.h:261: WARNING: Inline emphasis start-string without end-string.
   include/linux/devfreq.h:281: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/dmaengine/client.rst:203: WARNING: Unexpected indentation.
   Documentation/driver-api/dmaengine/client.rst:204: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/dmaengine/client.rst:210: WARNING: Unexpected indentation.
   Documentation/driver-api/dmaengine/client.rst:211: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/dmaengine/client.rst:220: WARNING: Unexpected indentation.
   Documentation/driver-api/dmaengine/client.rst:221: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/dmaengine/client.rst:229: WARNING: Unexpected indentation.
   Documentation/driver-api/dmaengine/client.rst:230: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/dmaengine/provider.rst:270: WARNING: Unexpected indentation.
   Documentation/driver-api/dmaengine/provider.rst:273: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/dmaengine/provider.rst:288: WARNING: Unexpected indentation.
   Documentation/driver-api/dmaengine/provider.rst:290: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/driver-api/driver-model/driver.rst:215: WARNING: Inline emphasis start-string without end-string.
   Documentation/driver-api/driver-model/driver.rst:215: WARNING: Inline emphasis start-string without end-string.
   Documentation/filesystems/fuse.rst:2: WARNING: Explicit markup ends without a blank line; unexpected unindent.
   Documentation/filesystems/ubifs-authentication.rst:94: WARNING: Inline interpreted text or phrase reference start-string without end-string.
   Documentation/trace/events.rst:589: WARNING: Definition list ends without a blank line; unexpected unindent.
   Documentation/trace/events.rst:620: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:623: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:626: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:703: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:697: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:722: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:775: WARNING: Definition list ends without a blank line; unexpected unindent.
   Documentation/trace/events.rst:814: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:817: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:820: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:823: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:826: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:829: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:832: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:844: WARNING: Unexpected indentation.
   Documentation/trace/events.rst:845: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/trace/events.rst:849: WARNING: Unexpected indentation.
   Documentation/trace/events.rst:850: WARNING: Block quote ends without a blank line; unexpected unindent.
   Documentation/trace/events.rst:883: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:886: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:889: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:895: WARNING: Bullet list ends without a blank line; unexpected unindent.
   Documentation/trace/events.rst:895: WARNING: Inline emphasis start-string without end-string.
   Documentation/trace/events.rst:968: WARNING: Inline emphasis start-string without end-string.
   fs/inode.c:1608: WARNING: Inline emphasis start-string without end-string.
   fs/inode.c:1608: WARNING: Inline emphasis start-string without end-string.
   fs/inode.c:1614: WARNING: Inline emphasis start-string without end-string.
   fs/seq_file.c:40: WARNING: Inline strong start-string without end-string.

vim +203 drivers/gpu/drm/drm_encoder.c

   184	
   185	/**
   186	 * drm_simple_encoder_init - Init a preallocated encoder
   187	 * @dev: drm device
   188	 * @funcs: callbacks for this encoder
   189	 * @encoder_type: user visible type of the encoder
   190	 * @name: printf style format string for the encoder name, or NULL
   191	 *        for default name
   192	 *
   193	 * Initialises a preallocated encoder that has no further functionality. The
   194	 * encoder will be released automatically.
   195	 *
   196	 * Returns:
   197	 * Zero on success, error code on failure.
   198	 */
   199	int drm_simple_encoder_init(struct drm_device *dev,
   200				    struct drm_encoder *encoder,
   201				    int encoder_type, const char *name, ...)
   202	{
 > 203		char *namestr = NULL;
   204		int ret;
   205	
   206		if (name) {
   207			va_list ap;
   208	
   209			va_start(ap, name);
   210			namestr = kvasprintf(GFP_KERNEL, name, ap);
   211			va_end(ap);
   212			if (!namestr)
   213				return -ENOMEM;
   214		}
   215	
   216		ret = __drm_encoder_init(dev, encoder,
   217					 &drm_simple_encoder_funcs_cleanup,
   218					 encoder_type, namestr);
   219		if (ret)
   220			goto err_kfree;
   221	
   222		return 0;
   223	
   224	err_kfree:
   225		if (name)
   226			kfree(namestr);
   227		return ret;
   228	}
   229	EXPORT_SYMBOL(drm_simple_encoder_init);
   230	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index ffe691a1bf34..1a65cab1f310 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -178,6 +178,122 @@  int drm_encoder_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_encoder_init);
 
+static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = {
+	.destroy = drm_encoder_cleanup,
+};
+
+/**
+ * drm_simple_encoder_init - Init a preallocated encoder
+ * @dev: drm device
+ * @funcs: callbacks for this encoder
+ * @encoder_type: user visible type of the encoder
+ * @name: printf style format string for the encoder name, or NULL
+ *        for default name
+ *
+ * Initialises a preallocated encoder that has no further functionality. The
+ * encoder will be released automatically.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_simple_encoder_init(struct drm_device *dev,
+			    struct drm_encoder *encoder,
+			    int encoder_type, const char *name, ...)
+{
+	char *namestr = NULL;
+	int ret;
+
+	if (name) {
+		va_list ap;
+
+		va_start(ap, name);
+		namestr = kvasprintf(GFP_KERNEL, name, ap);
+		va_end(ap);
+		if (!namestr)
+			return -ENOMEM;
+	}
+
+	ret = __drm_encoder_init(dev, encoder,
+				 &drm_simple_encoder_funcs_cleanup,
+				 encoder_type, namestr);
+	if (ret)
+		goto err_kfree;
+
+	return 0;
+
+err_kfree:
+	if (name)
+		kfree(namestr);
+	return ret;
+}
+EXPORT_SYMBOL(drm_simple_encoder_init);
+
+static void drm_encoder_destroy(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+
+	drm_encoder_cleanup(encoder);
+	devm_kfree(dev->dev, encoder);
+}
+
+static const struct drm_encoder_funcs drm_simple_encoder_funcs_destroy = {
+	.destroy = drm_encoder_destroy,
+};
+
+/**
+ * drm_simple_encoder_create - Allocate and initialize an encoder
+ * @dev: drm device
+ * @encoder_type: user visible type of the encoder
+ * @name: printf style format string for the encoder name, or NULL for
+ *        default name
+ *
+ * Allocates and initialises an encoder that has no further functionality. The
+ * encoder will be released automatically.
+ *
+ * Returns:
+ * The encoder on success, a pointer-encoder error code on failure.
+ */
+struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
+					      int encoder_type,
+					      const char *name, ...)
+{
+	char *namestr = NULL;
+	struct drm_encoder *encoder;
+	int ret;
+
+	encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
+	if (!encoder)
+		return ERR_PTR(-ENOMEM);
+
+	if (name) {
+		va_list ap;
+
+		va_start(ap, name);
+		namestr = kvasprintf(GFP_KERNEL, name, ap);
+		va_end(ap);
+		if (!namestr) {
+			ret = -ENOMEM;
+			goto err_devm_kfree;
+		}
+	}
+
+	ret = __drm_encoder_init(dev, encoder,
+				 &drm_simple_encoder_funcs_destroy,
+				 encoder_type, namestr);
+	if (ret)
+		goto err_kfree;
+
+	return encoder;
+
+err_kfree:
+	if (name)
+		kfree(namestr);
+err_devm_kfree:
+	devm_kfree(dev->dev, encoder);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(drm_simple_encoder_create);
+
 /**
  * drm_encoder_cleanup - cleans up an initialised encoder
  * @encoder: encoder to cleanup
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 5623994b6e9e..0214f6cf9de6 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -190,6 +190,16 @@  int drm_encoder_init(struct drm_device *dev,
 		     const struct drm_encoder_funcs *funcs,
 		     int encoder_type, const char *name, ...);
 
+__printf(4, 5)
+int drm_simple_encoder_init(struct drm_device *dev,
+			    struct drm_encoder *encoder,
+			    int encoder_type, const char *name, ...);
+
+__printf(3, 4)
+struct drm_encoder *drm_simple_encoder_create(struct drm_device *dev,
+					      int encoder_type,
+					      const char *name, ...);
+
 /**
  * drm_encoder_index - find the index of a registered encoder
  * @encoder: encoder to find index for