soc: qcom: smem_state: Add devm_qcom_smem_state_get()
authorStephan Gerhold <stephan@gerhold.net>
Fri, 18 Jun 2021 11:15:54 +0000 (13:15 +0200)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Wed, 23 Jun 2021 18:35:12 +0000 (13:35 -0500)
It is easy to forget to call qcom_smem_state_put() after
a qcom_smem_state_get(). Introduce a devm_qcom_smem_state_get()
helper function that automates this so that qcom_smem_state_put()
is automatically called when a device is removed.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20210618111556.53416-1-stephan@gerhold.net
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/soc/qcom/smem_state.c
include/linux/soc/qcom/smem_state.h

index d2b5584..31faf4a 100644 (file)
@@ -151,6 +151,42 @@ void qcom_smem_state_put(struct qcom_smem_state *state)
 }
 EXPORT_SYMBOL_GPL(qcom_smem_state_put);
 
+static void devm_qcom_smem_state_release(struct device *dev, void *res)
+{
+       qcom_smem_state_put(*(struct qcom_smem_state **)res);
+}
+
+/**
+ * devm_qcom_smem_state_get() - acquire handle to a devres managed state
+ * @dev:       client device pointer
+ * @con_id:    name of the state to lookup
+ * @bit:       flags from the state reference, indicating which bit's affected
+ *
+ * Returns handle to the state, or ERR_PTR(). qcom_smem_state_put() is called
+ * automatically when @dev is removed.
+ */
+struct qcom_smem_state *devm_qcom_smem_state_get(struct device *dev,
+                                                const char *con_id,
+                                                unsigned *bit)
+{
+       struct qcom_smem_state **ptr, *state;
+
+       ptr = devres_alloc(devm_qcom_smem_state_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       state = qcom_smem_state_get(dev, con_id, bit);
+       if (!IS_ERR(state)) {
+               *ptr = state;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return state;
+}
+EXPORT_SYMBOL_GPL(devm_qcom_smem_state_get);
+
 /**
  * qcom_smem_state_register() - register a new state
  * @of_node:   of_node used for matching client lookups
index 63ad8cd..652c015 100644 (file)
@@ -14,6 +14,7 @@ struct qcom_smem_state_ops {
 #ifdef CONFIG_QCOM_SMEM_STATE
 
 struct qcom_smem_state *qcom_smem_state_get(struct device *dev, const char *con_id, unsigned *bit);
+struct qcom_smem_state *devm_qcom_smem_state_get(struct device *dev, const char *con_id, unsigned *bit);
 void qcom_smem_state_put(struct qcom_smem_state *);
 
 int qcom_smem_state_update_bits(struct qcom_smem_state *state, u32 mask, u32 value);
@@ -29,6 +30,13 @@ static inline struct qcom_smem_state *qcom_smem_state_get(struct device *dev,
        return ERR_PTR(-EINVAL);
 }
 
+static inline struct qcom_smem_state *devm_qcom_smem_state_get(struct device *dev,
+                                                              const char *con_id,
+                                                              unsigned *bit)
+{
+       return ERR_PTR(-EINVAL);
+}
+
 static inline void qcom_smem_state_put(struct qcom_smem_state *state)
 {
 }