Re: [PATCH v5 2/3] firmware: add Exynos ACPM protocol driver
From: Tudor Ambarus <tudor.ambarus@linaro.org>
Date: 2025-01-07 10:50:03
Also in:
linux-arm-kernel, linux-samsung-soc, lkml
On 1/6/25 10:20 AM, Tudor Ambarus wrote:
quoted
quoted
quoted
quoted
+static const struct acpm_handle *acpm_get_by_phandle(struct device_node *np, + const char *property) +{ + struct acpm_handle *handle = NULL; + struct device_node *acpm_np; + struct acpm_info *info; + + if (!np) { + pr_err("I need a device pointer\n"); + return ERR_PTR(-EINVAL); + } + + acpm_np = of_parse_phandle(np, property, 0); + if (!acpm_np) + return ERR_PTR(-ENODEV); + + mutex_lock(&acpm_list_mutex); + list_for_each_entry(info, &acpm_list, node) { + if (acpm_np == info->dev->of_node) { + handle = &info->handle; + info->users++; + break; + } + } + mutex_unlock(&acpm_list_mutex); + of_node_put(acpm_np); +You also need device links and probably try_module_get. See clk.c clk_hw_create_clk() or of_qcom_ice_get(). Interestingly, none of them perform both operations, which I think is necessary. I think you could also avoid entire list and mutex by using platform_get_drvdata(), see of_qcom_ice_get().
[snip, irrelevant now] I made my mind, I think the solution is threefold. 1/ use kref with a release callback so that the firmware drvdata will be destroyed only when there are no consumers. Example: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e7c57355a3bc617fc220234889e49fe722a6305 2/ In get_handle() after kref_get_unless_zero() succeeds, I'll be calling try_module_get() for supplier. Even if kref will make sure that consumers will still have a valid supplier drvdata, I'd like to delete the supplier module when there are no consumers left. 3/ use device_link_add() so that when the supplier device unbinds, to unbind the consumer devices as well. I'll implement these. Cheers, ta