|
|
@@ -1781,6 +1781,89 @@ const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle);
|
|
|
|
|
|
+/**
|
|
|
+ * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
|
|
|
+ * @np: device node
|
|
|
+ * @propname: property name containing phandle on TISCI node
|
|
|
+ *
|
|
|
+ * NOTE: The function does not track individual clients of the framework
|
|
|
+ * and is expected to be maintained by caller of TI SCI protocol library.
|
|
|
+ * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle
|
|
|
+ * Return: pointer to handle if successful, else:
|
|
|
+ * -EPROBE_DEFER if the instance is not ready
|
|
|
+ * -ENODEV if the required node handler is missing
|
|
|
+ * -EINVAL if invalid conditions are encountered.
|
|
|
+ */
|
|
|
+const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
|
|
|
+ const char *property)
|
|
|
+{
|
|
|
+ struct ti_sci_handle *handle = NULL;
|
|
|
+ struct device_node *ti_sci_np;
|
|
|
+ struct ti_sci_info *info;
|
|
|
+ struct list_head *p;
|
|
|
+
|
|
|
+ if (!np) {
|
|
|
+ pr_err("I need a device pointer\n");
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ ti_sci_np = of_parse_phandle(np, property, 0);
|
|
|
+ if (!ti_sci_np)
|
|
|
+ return ERR_PTR(-ENODEV);
|
|
|
+
|
|
|
+ mutex_lock(&ti_sci_list_mutex);
|
|
|
+ list_for_each(p, &ti_sci_list) {
|
|
|
+ info = list_entry(p, struct ti_sci_info, node);
|
|
|
+ if (ti_sci_np == info->dev->of_node) {
|
|
|
+ handle = &info->handle;
|
|
|
+ info->users++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mutex_unlock(&ti_sci_list_mutex);
|
|
|
+ of_node_put(ti_sci_np);
|
|
|
+
|
|
|
+ if (!handle)
|
|
|
+ return ERR_PTR(-EPROBE_DEFER);
|
|
|
+
|
|
|
+ return handle;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle);
|
|
|
+
|
|
|
+/**
|
|
|
+ * devm_ti_sci_get_by_phandle() - Managed get handle using phandle
|
|
|
+ * @dev: Device pointer requesting TISCI handle
|
|
|
+ * @propname: property name containing phandle on TISCI node
|
|
|
+ *
|
|
|
+ * NOTE: This releases the handle once the device resources are
|
|
|
+ * no longer needed. MUST NOT BE released with ti_sci_put_handle.
|
|
|
+ * The function does not track individual clients of the framework
|
|
|
+ * and is expected to be maintained by caller of TI SCI protocol library.
|
|
|
+ *
|
|
|
+ * Return: 0 if all went fine, else corresponding error.
|
|
|
+ */
|
|
|
+const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
|
|
|
+ const char *property)
|
|
|
+{
|
|
|
+ const struct ti_sci_handle *handle;
|
|
|
+ const struct ti_sci_handle **ptr;
|
|
|
+
|
|
|
+ ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
|
|
|
+ if (!ptr)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+ handle = ti_sci_get_by_phandle(dev_of_node(dev), property);
|
|
|
+
|
|
|
+ if (!IS_ERR(handle)) {
|
|
|
+ *ptr = handle;
|
|
|
+ devres_add(dev, ptr);
|
|
|
+ } else {
|
|
|
+ devres_free(ptr);
|
|
|
+ }
|
|
|
+
|
|
|
+ return handle;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle);
|
|
|
+
|
|
|
static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
|
|
|
void *cmd)
|
|
|
{
|