power: domain: ti_sci_power_domains: Add support for exclusive and shared access
[platform/kernel/u-boot.git] / drivers / power / domain / ti-sci-power-domain.c
index aafde62..b9cd37b 100644 (file)
@@ -13,6 +13,7 @@
 #include <errno.h>
 #include <power-domain-uclass.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
@@ -56,11 +57,16 @@ 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);
@@ -85,6 +91,28 @@ static int ti_sci_power_domain_off(struct power_domain *pd)
        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 */ }
@@ -95,6 +123,7 @@ static struct power_domain_ops ti_sci_power_domain_ops = {
        .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) = {