[Intel-gfx] [PATCH v2 02/17] drm/atomic: Allow drivers to subclass drm_atomic_state, v3

2015-05-18 Thread Daniel Vetter
On Mon, May 18, 2015 at 10:06:40AM +0200, Maarten Lankhorst wrote:
> Drivers may need to store the state of shared resources, such as PLLs
> or FIFO space, into the atomic state. Allow this by making it possible
> to subclass drm_atomic_state.
> 
> Changes since v1:
> - Change member names for functions to atomic_state_(alloc,clear)
> - Change __drm_atomic_state_new to drm_atomic_state_init
> - Allow free function to be overridden too, in case extra memory is
>   allocated in alloc.
> Changes since v2:
> - Rename *_default_free to default_release, to make clear it doesn't
>   free the state object itself.

I'd have gone with just _release since we don't have a ->release hook nor
a drm_atomic_helper_state_release wrapper. But that's really a bikeshed
now ;-)

> Cc: dri-devel at lists.freedesktop.org
> Acked-by: Ander Conselvan de Oliveira  intel.com>
> Signed-off-by: Maarten Lankhorst 

Applied to topic/drm-misc, thanks.
-Daniel

> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index c6277a4a1f2f..cd1b16b25716 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -30,7 +30,15 @@
>  #include 
>  #include 
>  
> -static void kfree_state(struct drm_atomic_state *state)
> +/**
> + * drm_atomic_state_default_release -
> + * release memory initialized by drm_atomic_state_init
> + * @state: atomic state
> + *
> + * Free all the memory allocated by drm_atomic_state_init.
> + * This is useful for drivers that subclass the atomic state.
> + */
> +void drm_atomic_state_default_release(struct drm_atomic_state *state)
>  {
>   kfree(state->connectors);
>   kfree(state->connector_states);
> @@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state)
>   kfree(state->crtc_states);
>   kfree(state->planes);
>   kfree(state->plane_states);
> - kfree(state);
>  }
> +EXPORT_SYMBOL(drm_atomic_state_default_release);
>  
>  /**
> - * drm_atomic_state_alloc - allocate atomic state
> + * drm_atomic_state_init - init new atomic state
>   * @dev: DRM device
> + * @state: atomic state
>   *
> - * This allocates an empty atomic state to track updates.
> + * Default implementation for filling in a new atomic state.
> + * This is useful for drivers that subclass the atomic state.
>   */
> -struct drm_atomic_state *
> -drm_atomic_state_alloc(struct drm_device *dev)
> +int
> +drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
>  {
> - struct drm_atomic_state *state;
> -
> - state = kzalloc(sizeof(*state), GFP_KERNEL);
> - if (!state)
> - return NULL;
> -
>   /* TODO legacy paths should maybe do a better job about
>* setting this appropriately?
>*/
> @@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev)
>  
>   state->dev = dev;
>  
> - DRM_DEBUG_ATOMIC("Allocate atomic state %p\n", state);
> + DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
>  
> - return state;
> + return 0;
>  fail:
> - kfree_state(state);
> + drm_atomic_state_default_release(state);
> + return -ENOMEM;
> +}
> +EXPORT_SYMBOL(drm_atomic_state_init);
> +
> +/**
> + * drm_atomic_state_alloc - allocate atomic state
> + * @dev: DRM device
> + *
> + * This allocates an empty atomic state to track updates.
> + */
> +struct drm_atomic_state *
> +drm_atomic_state_alloc(struct drm_device *dev)
> +{
> + struct drm_mode_config *config = >mode_config;
> + struct drm_atomic_state *state;
> +
> + if (!config->funcs->atomic_state_alloc) {
> + state = kzalloc(sizeof(*state), GFP_KERNEL);
> + if (!state)
> + return NULL;
> + if (drm_atomic_state_init(dev, state) < 0) {
> + kfree(state);
> + return NULL;
> + }
> + return state;
> + }
>  
> - return NULL;
> + return config->funcs->atomic_state_alloc(dev);
>  }
>  EXPORT_SYMBOL(drm_atomic_state_alloc);
>  
>  /**
> - * drm_atomic_state_clear - clear state object
> + * drm_atomic_state_default_clear - clear base atomic state
>   * @state: atomic state
>   *
> - * When the w/w mutex algorithm detects a deadlock we need to back off and 
> drop
> - * all locks. So someone else could sneak in and change the current modeset
> - * configuration. Which means that all the state assembled in @state is no
> - * longer an atomic update to the current state, but to some arbitrary 
> earlier
> - * state. Which could break assumptions the driver's ->atomic_check likely
> - * relies on.
> - *
> - * Hence we must clear all cached state and completely start over, using this
> - * function.
> + * Default implementation for clearing atomic state.
> + * This is useful for drivers that subclass the atomic state.
>   */
> -void drm_atomic_state_clear(struct drm_atomic_state *state)
> +void drm_atomic_state_default_clear(struct drm_atomic_state *state)
>  {
>   struct drm_device *dev = 

[PATCH v2 02/17] drm/atomic: Allow drivers to subclass drm_atomic_state, v3

2015-05-18 Thread Maarten Lankhorst
Drivers may need to store the state of shared resources, such as PLLs
or FIFO space, into the atomic state. Allow this by making it possible
to subclass drm_atomic_state.

Changes since v1:
- Change member names for functions to atomic_state_(alloc,clear)
- Change __drm_atomic_state_new to drm_atomic_state_init
- Allow free function to be overridden too, in case extra memory is
  allocated in alloc.
Changes since v2:
- Rename *_default_free to default_release, to make clear it doesn't
  free the state object itself.

Cc: dri-devel at lists.freedesktop.org
Acked-by: Ander Conselvan de Oliveira 
Signed-off-by: Maarten Lankhorst 

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c6277a4a1f2f..cd1b16b25716 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -30,7 +30,15 @@
 #include 
 #include 

-static void kfree_state(struct drm_atomic_state *state)
+/**
+ * drm_atomic_state_default_release -
+ * release memory initialized by drm_atomic_state_init
+ * @state: atomic state
+ *
+ * Free all the memory allocated by drm_atomic_state_init.
+ * This is useful for drivers that subclass the atomic state.
+ */
+void drm_atomic_state_default_release(struct drm_atomic_state *state)
 {
kfree(state->connectors);
kfree(state->connector_states);
@@ -38,24 +46,20 @@ static void kfree_state(struct drm_atomic_state *state)
kfree(state->crtc_states);
kfree(state->planes);
kfree(state->plane_states);
-   kfree(state);
 }
+EXPORT_SYMBOL(drm_atomic_state_default_release);

 /**
- * drm_atomic_state_alloc - allocate atomic state
+ * drm_atomic_state_init - init new atomic state
  * @dev: DRM device
+ * @state: atomic state
  *
- * This allocates an empty atomic state to track updates.
+ * Default implementation for filling in a new atomic state.
+ * This is useful for drivers that subclass the atomic state.
  */
-struct drm_atomic_state *
-drm_atomic_state_alloc(struct drm_device *dev)
+int
+drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
 {
-   struct drm_atomic_state *state;
-
-   state = kzalloc(sizeof(*state), GFP_KERNEL);
-   if (!state)
-   return NULL;
-
/* TODO legacy paths should maybe do a better job about
 * setting this appropriately?
 */
@@ -92,31 +96,50 @@ drm_atomic_state_alloc(struct drm_device *dev)

state->dev = dev;

-   DRM_DEBUG_ATOMIC("Allocate atomic state %p\n", state);
+   DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);

-   return state;
+   return 0;
 fail:
-   kfree_state(state);
+   drm_atomic_state_default_release(state);
+   return -ENOMEM;
+}
+EXPORT_SYMBOL(drm_atomic_state_init);
+
+/**
+ * drm_atomic_state_alloc - allocate atomic state
+ * @dev: DRM device
+ *
+ * This allocates an empty atomic state to track updates.
+ */
+struct drm_atomic_state *
+drm_atomic_state_alloc(struct drm_device *dev)
+{
+   struct drm_mode_config *config = >mode_config;
+   struct drm_atomic_state *state;
+
+   if (!config->funcs->atomic_state_alloc) {
+   state = kzalloc(sizeof(*state), GFP_KERNEL);
+   if (!state)
+   return NULL;
+   if (drm_atomic_state_init(dev, state) < 0) {
+   kfree(state);
+   return NULL;
+   }
+   return state;
+   }

-   return NULL;
+   return config->funcs->atomic_state_alloc(dev);
 }
 EXPORT_SYMBOL(drm_atomic_state_alloc);

 /**
- * drm_atomic_state_clear - clear state object
+ * drm_atomic_state_default_clear - clear base atomic state
  * @state: atomic state
  *
- * When the w/w mutex algorithm detects a deadlock we need to back off and drop
- * all locks. So someone else could sneak in and change the current modeset
- * configuration. Which means that all the state assembled in @state is no
- * longer an atomic update to the current state, but to some arbitrary earlier
- * state. Which could break assumptions the driver's ->atomic_check likely
- * relies on.
- *
- * Hence we must clear all cached state and completely start over, using this
- * function.
+ * Default implementation for clearing atomic state.
+ * This is useful for drivers that subclass the atomic state.
  */
-void drm_atomic_state_clear(struct drm_atomic_state *state)
+void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 {
struct drm_device *dev = state->dev;
struct drm_mode_config *config = >mode_config;
@@ -162,6 +185,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
state->plane_states[i] = NULL;
}
 }
+EXPORT_SYMBOL(drm_atomic_state_default_clear);
+
+/**
+ * drm_atomic_state_clear - clear state object
+ * @state: atomic state
+ *
+ * When the w/w mutex algorithm detects a deadlock we need to back off and drop
+ * all locks. So someone else could sneak in and change the current