clk: Provide OF helper to mark clocks as CRITICAL
authorLee Jones <lee.jones@linaro.org>
Thu, 11 Feb 2016 21:19:11 +0000 (13:19 -0800)
committerMichael Turquette <mturquette@baylibre.com>
Sat, 9 Apr 2016 18:58:11 +0000 (11:58 -0700)
This call matches clocks which have been marked as critical in DT
and sets the appropriate flag.  These flags can then be used to
mark the clock core flags appropriately prior to registration.

Legacy bindings requiring this feature must add the clock-critical
property to their binding descriptions, as it is not a part of
common-clock binding.

Cc: devicetree@vger.kernel.org
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Michael Turquette <mturquette@baylibre.com>
Link: lkml.kernel.org/r/1455225554-13267-4-git-send-email-mturquette@baylibre.com

drivers/clk/clk.c
include/linux/clk-provider.h

index dede0ce679e47e271537e99f716c92c91fb27bce..9f77cc67cdc379cc073a44d161f993eed4a5a84e 100644 (file)
@@ -3137,6 +3137,41 @@ static int parent_ready(struct device_node *np)
        }
 }
 
+/**
+ * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree
+ * @np: Device node pointer associated with clock provider
+ * @index: clock index
+ * @flags: pointer to clk_core->flags
+ *
+ * Detects if the clock-critical property exists and, if so, sets the
+ * corresponding CLK_IS_CRITICAL flag.
+ *
+ * Do not use this function. It exists only for legacy Device Tree
+ * bindings, such as the one-clock-per-node style that are outdated.
+ * Those bindings typically put all clock data into .dts and the Linux
+ * driver has no clock data, thus making it impossible to set this flag
+ * correctly from the driver. Only those drivers may call
+ * of_clk_detect_critical from their setup functions.
+ *
+ * Return: error code or zero on success
+ */
+int of_clk_detect_critical(struct device_node *np,
+                                         int index, unsigned long *flags)
+{
+       struct property *prop;
+       const __be32 *cur;
+       uint32_t idx;
+
+       if (!np || !flags)
+               return -EINVAL;
+
+       of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
+               if (index == idx)
+                       *flags |= CLK_IS_CRITICAL;
+
+       return 0;
+}
+
 /**
  * of_clk_init() - Scan and init clock providers from the DT
  * @matches: array of compatible values and init functions for providers.
index 0638b41545022c9bef5e93f4c38af1c78f1971f6..156286445a25c03f4e2d2592820156cfb8daaf36 100644 (file)
@@ -721,7 +721,8 @@ unsigned int of_clk_get_parent_count(struct device_node *np);
 int of_clk_parent_fill(struct device_node *np, const char **parents,
                       unsigned int size);
 const char *of_clk_get_parent_name(struct device_node *np, int index);
-
+int of_clk_detect_critical(struct device_node *np, int index,
+                           unsigned long *flags);
 void of_clk_init(const struct of_device_id *matches);
 
 #else /* !CONFIG_OF */
@@ -758,6 +759,11 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,
 {
        return NULL;
 }
+static inline int of_clk_detect_critical(struct device_node *np, int index,
+                                         unsigned long *flags)
+{
+       return 0;
+}
 static inline void of_clk_init(const struct of_device_id *matches) {}
 #endif /* CONFIG_OF */