soc: qcom: ice: introduce devm_of_qcom_ice_get
[ Upstream commit 1c13d6060d612601a61423f2e8fbf9e48126acca ] Callers of of_qcom_ice_get() leak the device reference taken by of_find_device_by_node(). Introduce devm variant for of_qcom_ice_get(). Existing consumers need the ICE instance for the entire life of their device, thus exporting qcom_ice_put() is not required. Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Reviewed-by: Abel Vesa <abel.vesa@linaro.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Link: https://lore.kernel.org/r/20250117-qcom-ice-fix-dev-leak-v2-1-1ffa5b6884cb@linaro.org Signed-off-by: Bjorn Andersson <andersson@kernel.org> Stable-dep-of: cbef7442fba5 ("mmc: sdhci-msm: fix dev reference leaked through of_qcom_ice_get") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a505075730
commit
d4f5f29c26
@@ -10,6 +10,7 @@
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
@@ -328,6 +329,53 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_qcom_ice_get);
|
||||
|
||||
static void qcom_ice_put(const struct qcom_ice *ice)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(ice->dev);
|
||||
|
||||
if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "ice"))
|
||||
platform_device_put(pdev);
|
||||
}
|
||||
|
||||
static void devm_of_qcom_ice_put(struct device *dev, void *res)
|
||||
{
|
||||
qcom_ice_put(*(struct qcom_ice **)res);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_of_qcom_ice_get() - Devres managed helper to get an ICE instance from
|
||||
* a DT node.
|
||||
* @dev: device pointer for the consumer device.
|
||||
*
|
||||
* This function will provide an ICE instance either by creating one for the
|
||||
* consumer device if its DT node provides the 'ice' reg range and the 'ice'
|
||||
* clock (for legacy DT style). On the other hand, if consumer provides a
|
||||
* phandle via 'qcom,ice' property to an ICE DT, the ICE instance will already
|
||||
* be created and so this function will return that instead.
|
||||
*
|
||||
* Return: ICE pointer on success, NULL if there is no ICE data provided by the
|
||||
* consumer or ERR_PTR() on error.
|
||||
*/
|
||||
struct qcom_ice *devm_of_qcom_ice_get(struct device *dev)
|
||||
{
|
||||
struct qcom_ice *ice, **dr;
|
||||
|
||||
dr = devres_alloc(devm_of_qcom_ice_put, sizeof(*dr), GFP_KERNEL);
|
||||
if (!dr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ice = of_qcom_ice_get(dev);
|
||||
if (!IS_ERR_OR_NULL(ice)) {
|
||||
*dr = ice;
|
||||
devres_add(dev, dr);
|
||||
} else {
|
||||
devres_free(dr);
|
||||
}
|
||||
|
||||
return ice;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_of_qcom_ice_get);
|
||||
|
||||
static int qcom_ice_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_ice *engine;
|
||||
|
@@ -34,4 +34,6 @@ int qcom_ice_program_key(struct qcom_ice *ice,
|
||||
int slot);
|
||||
int qcom_ice_evict_key(struct qcom_ice *ice, int slot);
|
||||
struct qcom_ice *of_qcom_ice_get(struct device *dev);
|
||||
struct qcom_ice *devm_of_qcom_ice_get(struct device *dev);
|
||||
|
||||
#endif /* __QCOM_ICE_H__ */
|
||||
|
Reference in New Issue
Block a user