summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLokesh Vutla <lokeshvutla@ti.com>2019-06-07 19:24:46 +0530
committerTom Rini <trini@konsulko.com>2019-07-26 21:49:23 -0400
commitcd041c8041486e33516b8df53f937bb117b682d2 (patch)
tree0355b84694ab8831fc329c47bacafeb864736438
parentc163af6cb8998ca8ffc350f9f522819aa2e9b82e (diff)
power: domain: ti_sci_power_domains: Add support for exclusive and shared access
TISCI protocol supports for enabling the device either with exclusive permissions for the requesting host or with sharing across the hosts. There are certain devices which are exclusive to Linux context and there are certain devices that are shared across different host contexts. So add support for getting this information from DT by increasing the power-domain cells to 2. For keeping the DT backward compatibility intact, defaulting the device permissions to set the exclusive flag set. In this case the power-domain-cells is 1. Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
-rw-r--r--drivers/power/domain/ti-sci-power-domain.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/power/domain/ti-sci-power-domain.c b/drivers/power/domain/ti-sci-power-domain.c
index aafde62cbf..b9cd37b612 100644
--- a/drivers/power/domain/ti-sci-power-domain.c
+++ b/drivers/power/domain/ti-sci-power-domain.c
@@ -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) = {