]> git.ipfire.org Git - thirdparty/u-boot.git/blobdiff - drivers/power/domain/ti-sci-power-domain.c
tree-wide: Replace http:// link with https:// link for ti.com
[thirdparty/u-boot.git] / drivers / power / domain / ti-sci-power-domain.c
index aafde62cbf0d1e9f3a69d30402de896c96174f8e..8d6abe13dbc6d3ccf0e500efb24674214a0ab99b 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Texas Instruments System Control Interface (TI SCI) power domain driver
  *
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
  *     Andreas Dannenberg <dannenberg@ti.com>
  *
  * Loosely based on Linux kernel ti_sci_pm_domains.c...
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <log.h>
+#include <malloc.h>
 #include <power-domain-uclass.h>
+#include <dm/device_compat.h>
+#include <linux/err.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
 
 /**
  * struct ti_sci_power_domain_data - pm domain controller information structure
@@ -39,31 +44,24 @@ static int ti_sci_power_domain_probe(struct udevice *dev)
        return 0;
 }
 
-static int ti_sci_power_domain_request(struct power_domain *pd)
-{
-       debug("%s(pd=%p)\n", __func__, pd);
-       return 0;
-}
-
-static int ti_sci_power_domain_free(struct power_domain *pd)
-{
-       debug("%s(pd=%p)\n", __func__, pd);
-       return 0;
-}
-
 static int ti_sci_power_domain_on(struct power_domain *pd)
 {
        struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev);
        const struct ti_sci_handle *sci = data->sci;
        const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
+       u8 flags = (uintptr_t)pd->priv;
        int ret;
 
        debug("%s(pd=%p)\n", __func__, pd);
 
-       ret = dops->get_device(sci, pd->id);
+       if (flags & TI_SCI_PD_EXCLUSIVE)
+               ret = dops->get_device_exclusive(sci, pd->id);
+       else
+               ret = dops->get_device(sci, pd->id);
+
        if (ret)
-               dev_err(power_domain->dev, "%s: get_device failed (%d)\n",
-                       __func__, ret);
+               dev_err(pd->dev, "%s: get_device(%lu) failed (%d)\n",
+                       __func__, pd->id, ret);
 
        return ret;
 }
@@ -79,22 +77,43 @@ static int ti_sci_power_domain_off(struct power_domain *pd)
 
        ret = dops->put_device(sci, pd->id);
        if (ret)
-               dev_err(power_domain->dev, "%s: put_device failed (%d)\n",
-                       __func__, ret);
+               dev_err(pd->dev, "%s: put_device(%lu) failed (%d)\n",
+                       __func__, pd->id, ret);
 
        return ret;
 }
 
+static int ti_sci_power_domain_of_xlate(struct power_domain *pd,
+                                       struct ofnode_phandle_args *args)
+{
+       u8 flags;
+
+       debug("%s(power_domain=%p)\n", __func__, pd);
+
+       if (args->args_count < 1) {
+               debug("Invalid args_count: %d\n", args->args_count);
+               return -EINVAL;
+       }
+
+       pd->id = args->args[0];
+       /* By default request for device exclusive */
+       flags = TI_SCI_PD_EXCLUSIVE;
+       if (args->args_count == 2)
+               flags = args->args[1] & TI_SCI_PD_EXCLUSIVE;
+       pd->priv = (void *)(uintptr_t)flags;
+
+       return 0;
+}
+
 static const struct udevice_id ti_sci_power_domain_of_match[] = {
        { .compatible = "ti,sci-pm-domain" },
        { /* sentinel */ }
 };
 
 static struct power_domain_ops ti_sci_power_domain_ops = {
-       .request = ti_sci_power_domain_request,
-       .free = ti_sci_power_domain_free,
        .on = ti_sci_power_domain_on,
        .off = ti_sci_power_domain_off,
+       .of_xlate = ti_sci_power_domain_of_xlate,
 };
 
 U_BOOT_DRIVER(ti_sci_pm_domains) = {
@@ -102,6 +121,6 @@ U_BOOT_DRIVER(ti_sci_pm_domains) = {
        .id = UCLASS_POWER_DOMAIN,
        .of_match = ti_sci_power_domain_of_match,
        .probe = ti_sci_power_domain_probe,
-       .priv_auto_alloc_size = sizeof(struct ti_sci_power_domain_data),
+       .priv_auto      = sizeof(struct ti_sci_power_domain_data),
        .ops = &ti_sci_power_domain_ops,
 };