Got it, but of_find_node_by_name () is holding a raw_spin_lock_irqsave () for concurrency, right ? please correct me if understanding is wrong.
On 2/22/2024 11:37 PM, Sahil Chandna wrote:
On 2/20/2024 5:58 PM, Mukesh Ojha wrote:
When llcc driver is enabled and llcc device is notwhat is the requirement for mutex lock here? Since we are only trying to find if node present or not
physically there on the SoC, client can get
-EPROBE_DEFER on calling llcc_slice_getd() and it
is possible they defer forever.
Let's add a check device availabilty and set the
appropriate applicable error in drv_data.
Signed-off-by: Mukesh Ojha <quic_mojha@xxxxxxxxxxx>
---
drivers/soc/qcom/llcc-qcom.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 4ca88eaebf06..cb336b183bba 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -769,6 +769,27 @@ static const struct qcom_sct_config x1e80100_cfgs = {
};
static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
+static DEFINE_MUTEX(dev_avail);
I was trying to avoid two parallel call from llcc_slice_getd() calling
parallel call to of_find_node_by_name() as it should be one time search for device presence to find a node and check if device is present or
not.
-Mukesh
Also, thinking about this, should the status of device present or not be saved in static variable instead of function call for each client ?+
+static bool is_llcc_device_available(void)
+{
+ static struct llcc_drv_data *ptr;
+
+ mutex_lock(&dev_avail);
+ if (!ptr) {
+ struct device_node *node;
+
+ node = of_find_node_by_name(NULL, "system-cache-controller");
+ if (!of_device_is_available(node)) {
+ pr_warn("llcc-qcom: system-cache-controller node not found\n");
+ drv_data = ERR_PTR(-ENODEV);
+ }
+ of_node_put(node);
+ ptr = drv_data;
+ }
+ mutex_unlock(&dev_avail);
+ return (PTR_ERR(ptr) != -ENODEV) ? true : false;
+}
/**
* llcc_slice_getd - get llcc slice descriptor
@@ -783,7 +804,7 @@ struct llcc_slice_desc *llcc_slice_getd(u32 uid)
struct llcc_slice_desc *desc;
u32 sz, count;
- if (IS_ERR(drv_data))
+ if (!is_llcc_device_available() || IS_ERR(drv_data))
return ERR_CAST(drv_data);
cfg = drv_data->cfg;