Hello Amit,

On Thu, May 08, 2014 at 08:07:56PM +0530, Amit Daniel Kachhap wrote:
> This patch is in preparation to add notfication support for cpufrequency
> cooling changes. This change also removes the unnecessary exposing of
> internal housekeeping structure via thermal_cooling_device->devdata to the
> users of cpufreq cooling APIs.
> 
> Signed-off-by: Amit Daniel Kachhap <amit.dan...@samsung.com>
> ---
>  drivers/thermal/cpu_cooling.c                      |   79 +++++++++++++++----
>  drivers/thermal/db8500_cpufreq_cooling.c           |    2 +-
>  drivers/thermal/samsung/exynos_thermal_common.c    |    2 +-
>  drivers/thermal/ti-soc-thermal/ti-thermal-common.c |    2 +-
>  include/linux/cpu_cooling.h                        |    5 +-
>  5 files changed, 68 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
> index 4246262..21f44d4 100644
> --- a/drivers/thermal/cpu_cooling.c
> +++ b/drivers/thermal/cpu_cooling.c
> @@ -50,16 +50,18 @@ struct cpufreq_cooling_device {
>       unsigned int cpufreq_state;
>       unsigned int cpufreq_val;
>       struct cpumask allowed_cpus;
> +     struct list_head node;
>  };
>  static DEFINE_IDR(cpufreq_idr);
>  static DEFINE_MUTEX(cooling_cpufreq_lock);
>  
> -static unsigned int cpufreq_dev_count;
> -
>  /* notify_table passes value to the CPUFREQ_ADJUST callback function. */
>  #define NOTIFY_INVALID NULL
>  static struct cpufreq_cooling_device *notify_device;
>  
> +/* A list to hold all the cpufreq cooling devices registered */
> +static LIST_HEAD(cpufreq_cooling_list);
> +
>  /**
>   * get_idr - function to get a unique id.
>   * @idr: struct idr * handle used to create a id.
> @@ -357,12 +359,23 @@ static int cpufreq_thermal_notifier(struct 
> notifier_block *nb,
>  static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
>                                unsigned long *state)
>  {
> -     struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
> -     struct cpumask *mask = &cpufreq_device->allowed_cpus;
> +     struct cpufreq_cooling_device *cpufreq_device = NULL;
> +     struct cpumask *mask = NULL;
>       unsigned int cpu;
>       unsigned int count = 0;
>       int ret;
>  
> +     mutex_lock(&cooling_cpufreq_lock);
> +     list_for_each_entry(cpufreq_device, &cpufreq_cooling_list, node)
> +             if (cpufreq_device->cool_dev == cdev)
> +                     break;
> +     mutex_unlock(&cooling_cpufreq_lock);
> +     if (!cpufreq_device) {
> +             /* Cooling device pointer not found */
> +             return -EINVAL;
> +     }
> +
> +     mask = &cpufreq_device->allowed_cpus;
>       cpu = cpumask_any(mask);
>  
>       ret = get_property(cpu, 0, &count, GET_MAXL);
> @@ -386,7 +399,17 @@ static int cpufreq_get_max_state(struct 
> thermal_cooling_device *cdev,
>  static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
>                                unsigned long *state)
>  {
> -     struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
> +     struct cpufreq_cooling_device *cpufreq_device = NULL;
> +
> +     mutex_lock(&cooling_cpufreq_lock);
> +     list_for_each_entry(cpufreq_device, &cpufreq_cooling_list, node)
> +             if (cpufreq_device->cool_dev == cdev)
> +                     break;
> +     mutex_unlock(&cooling_cpufreq_lock);
> +     if (!cpufreq_device) {
> +             /* Cooling device pointer not found */
> +             return -EINVAL;
> +     }
>  
>       *state = cpufreq_device->cpufreq_state;
>  
> @@ -406,7 +429,17 @@ static int cpufreq_get_cur_state(struct 
> thermal_cooling_device *cdev,
>  static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
>                                unsigned long state)
>  {
> -     struct cpufreq_cooling_device *cpufreq_device = cdev->devdata;
> +     struct cpufreq_cooling_device *cpufreq_device = NULL;
> +
> +     mutex_lock(&cooling_cpufreq_lock);
> +     list_for_each_entry(cpufreq_device, &cpufreq_cooling_list, node)
> +             if (cpufreq_device->cool_dev == cdev)
> +                     break;
> +     mutex_unlock(&cooling_cpufreq_lock);
> +     if (!cpufreq_device) {
> +             /* Cooling device pointer not found */
> +             return -EINVAL;
> +     }
>  
>       return cpufreq_apply_cooling(cpufreq_device, state);
>  }
> @@ -427,6 +460,7 @@ static struct notifier_block 
> thermal_cpufreq_notifier_block = {
>   * __cpufreq_cooling_register - helper function to create cpufreq cooling 
> device
>   * @np: a valid struct device_node to the cooling device device tree node
>   * @clip_cpus: cpumask of cpus where the frequency constraints will happen.
> + * @devdata: driver data pointer
>   *
>   * This interface function registers the cpufreq cooling device with the name
>   * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
> @@ -438,7 +472,7 @@ static struct notifier_block 
> thermal_cpufreq_notifier_block = {
>   */
>  static struct thermal_cooling_device *
>  __cpufreq_cooling_register(struct device_node *np,
> -                        const struct cpumask *clip_cpus)
> +                        const struct cpumask *clip_cpus, void *devdata)
>  {
>       struct thermal_cooling_device *cool_dev;
>       struct cpufreq_cooling_device *cpufreq_dev = NULL;
> @@ -477,7 +511,7 @@ __cpufreq_cooling_register(struct device_node *np,
>       snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
>                cpufreq_dev->id);
>  
> -     cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
> +     cool_dev = thermal_of_cooling_device_register(np, dev_name, devdata,
>                                                     &cpufreq_cooling_ops);
>       if (IS_ERR(cool_dev)) {
>               release_idr(&cpufreq_idr, cpufreq_dev->id);
> @@ -489,10 +523,11 @@ __cpufreq_cooling_register(struct device_node *np,
>       mutex_lock(&cooling_cpufreq_lock);
>  
>       /* Register the notifier for first cpufreq cooling device */
> -     if (cpufreq_dev_count == 0)
> +     if (list_empty(&cpufreq_cooling_list))
>               cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
>                                         CPUFREQ_POLICY_NOTIFIER);
> -     cpufreq_dev_count++;
> +
> +     list_add(&cpufreq_dev->node, &cpufreq_cooling_list);
>  
>       mutex_unlock(&cooling_cpufreq_lock);
>  
> @@ -502,6 +537,7 @@ __cpufreq_cooling_register(struct device_node *np,
>  /**
>   * cpufreq_cooling_register - function to create cpufreq cooling device.
>   * @clip_cpus: cpumask of cpus where the frequency constraints will happen.
> + * @devdata: driver data pointer
>   *
>   * This interface function registers the cpufreq cooling device with the name
>   * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq
> @@ -511,9 +547,9 @@ __cpufreq_cooling_register(struct device_node *np,
>   * on failure, it returns a corresponding ERR_PTR().
>   */
>  struct thermal_cooling_device *
> -cpufreq_cooling_register(const struct cpumask *clip_cpus)
> +cpufreq_cooling_register(const struct cpumask *clip_cpus, void *devdata)
>  {
> -     return __cpufreq_cooling_register(NULL, clip_cpus);
> +     return __cpufreq_cooling_register(NULL, clip_cpus, devdata);
>  }
>  EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
>  
> @@ -537,7 +573,7 @@ of_cpufreq_cooling_register(struct device_node *np,
>       if (!np)
>               return ERR_PTR(-EINVAL);
>  
> -     return __cpufreq_cooling_register(np, clip_cpus);
> +     return __cpufreq_cooling_register(np, clip_cpus, NULL);
>  }
>  EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register);
>  
> @@ -554,17 +590,26 @@ void cpufreq_cooling_unregister(struct 
> thermal_cooling_device *cdev)
>       if (!cdev)
>               return;
>  
> -     cpufreq_dev = cdev->devdata;
>       mutex_lock(&cooling_cpufreq_lock);
> -     cpufreq_dev_count--;
> +
> +     list_for_each_entry(cpufreq_dev, &cpufreq_cooling_list, node)
> +             if (cpufreq_dev->cool_dev == cdev)
> +                     break;
> +
> +     if (!cpufreq_dev) {
> +             /* Cooling device pointer not found */
> +             mutex_unlock(&cooling_cpufreq_lock);
> +             return;
> +     }

Because you are adding several times the same code to search through
your list of cdevs, I recommend adding at least a helper function to
perform this recurring operation.

Besides, are you sure you cannot keep both pointers, the cpufreq_dev and
the driver devdata? One way is to embedded the driver devdata inside the
cpufreq_dev and register cpufreq_dev. Then you would adapt the code to
fetch each pointer accordingly. What do you think?

> +     thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
> +     list_del(&cpufreq_dev->node);
>  
>       /* Unregister the notifier for the last cpufreq cooling device */
> -     if (cpufreq_dev_count == 0)
> +     if (list_empty(&cpufreq_cooling_list))
>               cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
>                                           CPUFREQ_POLICY_NOTIFIER);
>       mutex_unlock(&cooling_cpufreq_lock);
>  
> -     thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
>       release_idr(&cpufreq_idr, cpufreq_dev->id);
>       kfree(cpufreq_dev);
>  }
> diff --git a/drivers/thermal/db8500_cpufreq_cooling.c 
> b/drivers/thermal/db8500_cpufreq_cooling.c
> index 786d192..abb9bdd 100644
> --- a/drivers/thermal/db8500_cpufreq_cooling.c
> +++ b/drivers/thermal/db8500_cpufreq_cooling.c
> @@ -35,7 +35,7 @@ static int db8500_cpufreq_cooling_probe(struct 
> platform_device *pdev)
>               return -EPROBE_DEFER;
>  
>       cpumask_set_cpu(0, &mask_val);
> -     cdev = cpufreq_cooling_register(&mask_val);
> +     cdev = cpufreq_cooling_register(&mask_val, NULL);
>  
>       if (IS_ERR(cdev)) {
>               dev_err(&pdev->dev, "Failed to register cooling device\n");
> diff --git a/drivers/thermal/samsung/exynos_thermal_common.c 
> b/drivers/thermal/samsung/exynos_thermal_common.c
> index 3f5ad25..a7306fa 100644
> --- a/drivers/thermal/samsung/exynos_thermal_common.c
> +++ b/drivers/thermal/samsung/exynos_thermal_common.c
> @@ -369,7 +369,7 @@ int exynos_register_thermal(struct thermal_sensor_conf 
> *sensor_conf)
>       if (sensor_conf->cooling_data.freq_clip_count > 0) {
>               cpumask_set_cpu(0, &mask_val);
>               th_zone->cool_dev[th_zone->cool_dev_size] =
> -                                     cpufreq_cooling_register(&mask_val);
> +                             cpufreq_cooling_register(&mask_val, NULL);
>               if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) {
>                       dev_err(sensor_conf->dev,
>                               "Failed to register cpufreq cooling device\n");
> diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c 
> b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> index 9eec26d..7809db6 100644
> --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
> @@ -409,7 +409,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap 
> *bgp, int id)
>       }
>  
>       /* Register cooling device */
> -     data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
> +     data->cool_dev = cpufreq_cooling_register(cpu_present_mask, NULL);
>       if (IS_ERR(data->cool_dev)) {
>               dev_err(bgp->dev,
>                       "Failed to register cpufreq cooling device\n");
> diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h
> index c303d38..aaef7d8 100644
> --- a/include/linux/cpu_cooling.h
> +++ b/include/linux/cpu_cooling.h
> @@ -32,9 +32,10 @@
>  /**
>   * cpufreq_cooling_register - function to create cpufreq cooling device.
>   * @clip_cpus: cpumask of cpus where the frequency constraints will happen
> + * @devdata: driver data pointer
>   */
>  struct thermal_cooling_device *
> -cpufreq_cooling_register(const struct cpumask *clip_cpus);
> +cpufreq_cooling_register(const struct cpumask *clip_cpus, void *devdata);
>  
>  /**
>   * of_cpufreq_cooling_register - create cpufreq cooling device based on DT.
> @@ -63,7 +64,7 @@ void cpufreq_cooling_unregister(struct 
> thermal_cooling_device *cdev);
>  unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq);
>  #else /* !CONFIG_CPU_THERMAL */
>  static inline struct thermal_cooling_device *
> -cpufreq_cooling_register(const struct cpumask *clip_cpus)
> +cpufreq_cooling_register(const struct cpumask *clip_cpus, void *devdata)
>  {
>       return NULL;
>  }
> -- 
> 1.7.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to