Messages in this thread | | | Subject | Re: [Patch v5 3/6] thermal: Add generic power domain warming device driver. | From | Thara Gopinath <> | Date | Wed, 25 Mar 2020 10:35:31 -0400 |
| |
Hi Ulf, Thanks for the review!
On 3/23/20 11:57 AM, Ulf Hansson wrote:
--snip >> + >> +static void pd_warming_release(struct device *dev) >> +{ >> + kfree(dev); > > This is wrong, you should free a "struct pd_warming_device *". Use the > "container of" macro to get it from 'dev'.
Will fix this. > >> +} >> + >> +struct thermal_cooling_device * >> +of_pd_warming_register(struct device *parent, int pd_id) >> +{ >> + struct pd_warming_device *pd_wdev; >> + struct of_phandle_args pd_args; >> + char cdev_name[THERMAL_NAME_LENGTH]; >> + int ret; >> + >> + pd_wdev = kzalloc(sizeof(*pd_wdev), GFP_KERNEL); >> + if (!pd_wdev) >> + return ERR_PTR(-ENOMEM); >> + >> + dev_set_name(&pd_wdev->dev, "%s_%d_warming_dev", >> + dev_name(parent), pd_id); >> + pd_wdev->dev.parent = parent; >> + pd_wdev->dev.release = pd_warming_release; >> + >> + ret = device_register(&pd_wdev->dev); >> + if (ret) { >> + put_device(&pd_wdev->dev); >> + goto free_pd_wdev; >> + } >> + >> + ret = ida_simple_get(&pd_ida, 0, 0, GFP_KERNEL); >> + if (ret < 0) >> + goto unregister_device; > > If you use and ida, you might as well use it as a part of the > dev_set_name() above. > > That should give you a unique name, similar to how you use it for the > cdev_name below.
dev_set_name above already has a unique name with the power controller name and the power domain id. cdev on the other hand creates a virtual thermal device and needs a unique name.
> >> + >> + pd_wdev->id = ret; >> + >> + pd_args.np = parent->of_node; >> + pd_args.args[0] = pd_id; >> + pd_args.args_count = 1; >> + >> + ret = of_genpd_add_device(&pd_args, &pd_wdev->dev); >> + >> + if (ret) >> + goto remove_ida; >> + >> + ret = dev_pm_genpd_performance_state_count(&pd_wdev->dev); >> + if (ret < 0) >> + goto out_genpd; >> + >> + pd_wdev->max_state = ret - 1; >> + pm_runtime_enable(&pd_wdev->dev); >> + pd_wdev->runtime_resumed = false; >> + >> + snprintf(cdev_name, sizeof(cdev_name), "thermal-pd-%d", pd_wdev->id); >> + pd_wdev->cdev = thermal_of_cooling_device_register >> + (NULL, cdev_name, pd_wdev, >> + &pd_warming_device_ops); >> + if (IS_ERR(pd_wdev->cdev)) { >> + pr_err("unable to register %s cooling device\n", cdev_name); >> + ret = PTR_ERR(pd_wdev->cdev); >> + goto out_runtime_disable; >> + } >> + >> + return pd_wdev->cdev; >> + >> +out_runtime_disable: >> + pm_runtime_disable(&pd_wdev->dev); >> +out_genpd: >> + pm_genpd_remove_device(&pd_wdev->dev); >> +remove_ida: >> + ida_simple_remove(&pd_ida, pd_wdev->id); >> +unregister_device: >> + device_unregister(&pd_wdev->dev); >> + pd_warming_release(&pd_wdev->dev); > > This is wrong, drop this.
Oops . sorry . Will do. Will fix rest of the comments below as well.
> >> +free_pd_wdev: >> + kfree(pd_wdev); > > Since you should free this from the ->release() callback, there is no > need to do this here. > >> + return ERR_PTR(ret); >> +} >> +EXPORT_SYMBOL_GPL(of_pd_warming_register); >> + >> +void pd_warming_unregister(struct thermal_cooling_device *cdev) >> +{ >> + struct pd_warming_device *pd_wdev = cdev->devdata; >> + struct device *dev = &pd_wdev->dev; >> + >> + if (pd_wdev->runtime_resumed) { >> + dev_pm_genpd_set_performance_state(dev, 0); >> + pm_runtime_put(dev); >> + pd_wdev->runtime_resumed = false; >> + } >> + pm_runtime_disable(dev); >> + pm_genpd_remove_device(dev); >> + ida_simple_remove(&pd_ida, pd_wdev->id); >> + thermal_cooling_device_unregister(cdev); >> + kfree(pd_wdev); > > Don't use kfree here, but instead device_unregister(dev); > >> +} >> +EXPORT_SYMBOL_GPL(pd_warming_unregister); >> diff --git a/include/linux/pd_warming.h b/include/linux/pd_warming.h >> new file mode 100644 >> index 000000000000..550a5683b56d >> --- /dev/null >> +++ b/include/linux/pd_warming.h >> @@ -0,0 +1,29 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Copyright (c) 2019, Linaro Ltd. >> + */ >> +#ifndef __PWR_DOMAIN_WARMING_H__ >> +#define __PWR_DOMAIN_WARMING_H__ >> + >> +#include <linux/pm_domain.h> >> +#include <linux/thermal.h> >> + >> +#ifdef CONFIG_PWR_DOMAIN_WARMING_THERMAL >> +struct thermal_cooling_device * >> +of_pd_warming_register(struct device *parent, int pd_id); >> + >> +void pd_warming_unregister(struct thermal_cooling_device *cdev); >> + >> +#else >> +static inline struct thermal_cooling_device * >> +of_pd_warming_register(struct device *parent, int pd_id) >> +{ >> + return ERR_PTR(-ENOSYS); >> +} >> + >> +static inline void >> +pd_warming_unregister(struct thermal_cooling_device *cdev) >> +{ >> +} >> +#endif /* CONFIG_PWR_DOMAIN_WARMING_THERMAL */ >> +#endif /* __PWR_DOMAIN_WARMING_H__ */ >> -- >> 2.20.1 >> > > Besides the few things above, this looks good to me. > > Kind regards > Uffe >
-- Warm Regards Thara
| |