On 27/02/2019 20:58, Ulf Hansson wrote:
> Let's add a data pointer to the genpd_power_state struct, to allow a genpd
> backend driver to store per state specific data. To introduce the pointer,
> we need to change the way genpd deals with freeing of the corresponding
> allocated data.
> 
> More precisely, let's clarify the responsibility of whom that shall free
> the data, by adding a ->free_states() callback to the struct
> generic_pm_domain. The one allocating the data shall assign the callback,
> to allow genpd to invoke it from genpd_remove().
> 
> Cc: Lina Iyer <il...@codeaurora.org>
> Co-developed-by: Lina Iyer <lina.i...@linaro.org>
> Signed-off-by: Ulf Hansson <ulf.hans...@linaro.org>
> ---
> 
> Changes in v12:
>       - None.
> 
> ---
>  drivers/base/power/domain.c | 12 ++++++++++--
>  include/linux/pm_domain.h   |  4 +++-
>  2 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index 2c334c01fc43..03885c003c6a 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -1685,6 +1685,12 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain 
> *genpd,
>  }
>  EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
>  
> +static void genpd_free_default_power_state(struct genpd_power_state *states,
> +                                        unsigned int state_count)
> +{
> +     kfree(states);
> +}
> +
>  static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
>  {
>       struct genpd_power_state *state;
> @@ -1695,7 +1701,7 @@ static int genpd_set_default_power_state(struct 
> generic_pm_domain *genpd)
>  
>       genpd->states = state;
>       genpd->state_count = 1;
> -     genpd->free = state;
> +     genpd->free_states = genpd_free_default_power_state;
>  
>       return 0;
>  }
> @@ -1811,7 +1817,9 @@ static int genpd_remove(struct generic_pm_domain *genpd)
>       list_del(&genpd->gpd_list_node);
>       genpd_unlock(genpd);
>       cancel_work_sync(&genpd->power_off_work);
> -     kfree(genpd->free);
> +     if (genpd->free_states)

Is this test necessary as the free_states function is initialized with
the genpd_set_default_power_state() in any case?

> +             genpd->free_states(genpd->states, genpd->state_count);
> +
>       pr_debug("%s: removed %s\n", __func__, genpd->name);
>  
>       return 0;
> diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
> index 1ed5874bcee0..8e1399231753 100644
> --- a/include/linux/pm_domain.h
> +++ b/include/linux/pm_domain.h
> @@ -69,6 +69,7 @@ struct genpd_power_state {
>       s64 residency_ns;
>       struct fwnode_handle *fwnode;
>       ktime_t idle_time;
> +     void *data;
>  };
>  
>  struct genpd_lock_ops;
> @@ -110,9 +111,10 @@ struct generic_pm_domain {
>                          struct device *dev);
>       unsigned int flags;             /* Bit field of configs for genpd */
>       struct genpd_power_state *states;
> +     void (*free_states)(struct genpd_power_state *states,
> +                         unsigned int state_count);
>       unsigned int state_count; /* number of states */
>       unsigned int state_idx; /* state that genpd will go to when off */
> -     void *free; /* Free the state that was allocated for default */
>       ktime_t on_time;
>       ktime_t accounting_time;
>       const struct genpd_lock_ops *lock_ops;
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

Reply via email to