aboutsummaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorPeng Fan2020-05-05 20:28:40 +0800
committerStefano Babic2020-05-10 20:55:20 +0200
commit231401de2eab8b8e503eb21afb6579ec24f872c6 (patch)
tree34f496d11fca0c3d0faa25839a98ed43ca25d3ec /drivers/power
parent8103767256dde5e0ca949790f0896268ae0832d3 (diff)
imx: imx8qm/imx8qxp: Power down the resources before SPL jump to u-boot
Make sure that all devices that are powered up by SPL are powered down before entering into the u-boot. Otherwise the subsystem/device will never be powered down by SCFW, due to SPL and u-boot are in different partitions. Benefiting from power domain driver, this patch implements the function "imx8_power_off_pd_devices" to power off all active devices. Signed-off-by: Peng Fan <peng.fan@nxp.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/domain/imx8-power-domain-legacy.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c
index f679df9e5d1..7ba4056e2d5 100644
--- a/drivers/power/domain/imx8-power-domain-legacy.c
+++ b/drivers/power/domain/imx8-power-domain-legacy.c
@@ -11,6 +11,7 @@
#include <asm/arch/power-domain.h>
#include <dm/device-internal.h>
#include <dm/device.h>
+#include <dm/uclass-internal.h>
#include <asm/arch/sci/sci.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -19,6 +20,40 @@ struct imx8_power_domain_priv {
bool state_on;
};
+static bool check_device_power_off(struct udevice *dev,
+ const char *permanent_on_devices[],
+ int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (!strcmp(dev->name, permanent_on_devices[i]))
+ return false;
+ }
+
+ return true;
+}
+
+void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size)
+{
+ struct udevice *dev;
+ struct power_domain pd;
+
+ for (uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev); dev;
+ uclass_find_next_device(&dev)) {
+ if (!device_active(dev))
+ continue;
+ /*
+ * Power off active pd devices except the permanent
+ * power on devices
+ */
+ if (check_device_power_off(dev, permanent_on_devices, size)) {
+ pd.dev = dev;
+ power_domain_off(&pd);
+ }
+ }
+}
+
int imx8_power_domain_lookup_name(const char *name,
struct power_domain *power_domain)
{