/** * gpufreq_cooling_unregister - function to remove gpufreq cooling device. * @cdev: thermal cooling device pointer. * * This interface function unregisters the "thermal-gpufreq-%x" cooling device. */ void gpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { struct gpufreq_cooling_device *gpufreq_dev; if (!cdev) return; gpufreq_dev = cdev->devdata; thermal_cooling_device_unregister(gpufreq_dev->cool_dev); release_idr(&gpufreq_idr, gpufreq_dev->id); kfree(gpufreq_dev); }
/** * clock_cooling_unregister - function to remove clock cooling device. * @cdev: thermal cooling device pointer. * * This interface function unregisters the "thermal-clock-%x" cooling device. */ void clock_cooling_unregister(struct thermal_cooling_device *cdev) { struct clock_cooling_device *ccdev; if (!cdev) return; ccdev = cdev->devdata; clk_notifier_unregister(ccdev->clk, &ccdev->clk_rate_change_nb); dev_pm_opp_free_cpufreq_table(ccdev->dev, &ccdev->freq_table); thermal_cooling_device_unregister(ccdev->cdev); release_idr(ccdev->id); }
/** * isp_cooling_unregister - function to remove isp cooling device. * @cdev: thermal cooling device pointer. * * This interface function unregisters the "thermal-isp-%x" cooling device. */ void isp_cooling_unregister(struct thermal_cooling_device *cdev) { struct isp_cooling_device *isp_dev; if (!cdev) return; isp_dev = cdev->devdata; mutex_lock(&cooling_isp_lock); isp_dev_count--; mutex_unlock(&cooling_isp_lock); thermal_cooling_device_unregister(isp_dev->cool_dev); release_idr(&isp_idr, isp_dev->id); kfree(isp_dev); }
/** * cpufreq_cooling_unregister - function to remove cpufreq cooling device. * @cdev: thermal cooling device pointer. * * This interface function unregisters the "thermal-cpufreq-%x" cooling device. */ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { struct cpufreq_cooling_device *cpufreq_dev = cdev->devdata; mutex_lock(&cooling_cpufreq_lock); cpufreq_dev_count--; /* Unregister the notifier for the last cpufreq cooling device */ if (cpufreq_dev_count == 0) 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); }
/** * __isp_cooling_register - helper function to create isp cooling device * @np: a valid struct device_node to the cooling device device tree node * @clip_isp: ispmask of isp where the fps constraints will happen. * * This interface function registers the isp cooling device with the name * "thermal-isp-%x". This api can support multiple instances of isp * cooling devices. It also gives the opportunity to link the cooling device * with a device tree node, in order to bind it via the thermal DT code. * * Return: a valid struct thermal_cooling_device pointer on success, * on failure, it returns a corresponding ERR_PTR(). */ static struct thermal_cooling_device * __isp_cooling_register(struct device_node *np, const struct cpumask *clip_isp) { struct thermal_cooling_device *cool_dev; struct isp_cooling_device *isp_dev = NULL; char dev_name[THERMAL_NAME_LENGTH]; int ret = 0; isp_dev = kzalloc(sizeof(struct isp_cooling_device), GFP_KERNEL); if (!isp_dev) return ERR_PTR(-ENOMEM); ret = get_idr(&isp_idr, &isp_dev->id); if (ret) { kfree(isp_dev); return ERR_PTR(-EINVAL); } snprintf(dev_name, sizeof(dev_name), "thermal-isp-%d", isp_dev->id); cool_dev = thermal_of_cooling_device_register(np, dev_name, isp_dev, &isp_cooling_ops); if (IS_ERR(cool_dev)) { release_idr(&isp_idr, isp_dev->id); kfree(isp_dev); return cool_dev; } isp_dev->cool_dev = cool_dev; isp_dev->isp_state = 0; mutex_lock(&cooling_isp_lock); isp_dev_count++; mutex_unlock(&cooling_isp_lock); return cool_dev; }
/** * cpufreq_cooling_register - function to create cpufreq cooling device. * @clip_cpus: cpumask of cpus where the frequency constraints will happen. * * This interface function registers the cpufreq cooling device with the name * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq * cooling devices. * * Return: a valid struct thermal_cooling_device pointer on success, * on failure, it returns a corresponding ERR_PTR(). */ struct thermal_cooling_device * cpufreq_cooling_register(const struct cpumask *clip_cpus) { struct thermal_cooling_device *cool_dev; struct cpufreq_cooling_device *cpufreq_dev = NULL; unsigned int min = 0, max = 0; char dev_name[THERMAL_NAME_LENGTH]; int ret = 0, i; struct cpufreq_policy policy; /* Verify that all the clip cpus have same freq_min, freq_max limit */ for_each_cpu(i, clip_cpus) { /* continue if cpufreq policy not found and not return error */ if (!cpufreq_get_policy(&policy, i)) continue; if (min == 0 && max == 0) { min = policy.cpuinfo.min_freq; max = policy.cpuinfo.max_freq; } else { if (min != policy.cpuinfo.min_freq || max != policy.cpuinfo.max_freq) return ERR_PTR(-EINVAL); } } cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device), GFP_KERNEL); if (!cpufreq_dev) return ERR_PTR(-ENOMEM); cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); if (ret) { kfree(cpufreq_dev); return ERR_PTR(-EINVAL); } snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", cpufreq_dev->id); cool_dev = thermal_cooling_device_register(dev_name, cpufreq_dev, &cpufreq_cooling_ops); if (!cool_dev) { release_idr(&cpufreq_idr, cpufreq_dev->id); kfree(cpufreq_dev); return ERR_PTR(-EINVAL); } cpufreq_dev->cool_dev = cool_dev; cpufreq_dev->cpufreq_state = 0; mutex_lock(&cooling_cpufreq_lock); /* Register the notifier for first cpufreq cooling device */ if (cpufreq_dev_count == 0) cpufreq_register_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); cpufreq_dev_count++; mutex_unlock(&cooling_cpufreq_lock); return cool_dev; }