summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMostafa Saleh <smostafa@google.com>2023-07-25 10:25:31 +0000
committerJing Wang <jwangh@google.com>2023-07-31 18:26:03 +0000
commitaa23e3b4665dd89ab98c69ac9c9b1d8ebc210a47 (patch)
treebfa7109319248574d30f1577b4deed2be51faf37
parent91601080504220c9425bc4e11982659e86c4e81c (diff)
downloadgs-aa23e3b4665dd89ab98c69ac9c9b1d8ebc210a47.tar.gz
phy-exynos-usbdrd: Power manage HSI0-PD S2MPU without RPM
In GS201, the behaviour was to eagerly resume/suspend s2mpu from post ON and pre OFF hooks, without RPM. In Zuma, to avoid symbol dependency between exynos-pd (which depends on this driver) calls to S2MPU driver were removed, and the suspend /resume was done through kernel run time PM through put/get sync. However, it turned out this doesn't work during system suspend, as the kernel disable rpm for devices which prevents the suspend notification to reach the S2MPU driver, so the hypervisor still thinks the S2MPU is on while it is not, causing the crash upon MMIO access. This is done from: pm_suspend => enter_state => suspend_devices_and_enter => dpm_suspend_start => dpm_prepare => device_prepare => pm_runtime_get_noresume To fix this, we use a similar mechanism to Pixel-7, to directly notify the hypervisor. To avoid symbol dependency, the driver calls to KVM IOMMU directly, which is safe. Bug: 292146325 Change-Id: I6d4b0024422caa58b6cef78d8ac43e6b367e3800 Signed-off-by: Mostafa Saleh <smostafa@google.com>
-rw-r--r--drivers/phy/samsung/phy-exynos-usbdrd-eusb.c8
-rw-r--r--drivers/phy/samsung/phy-exynos-usbdrd.c8
2 files changed, 12 insertions, 4 deletions
diff --git a/drivers/phy/samsung/phy-exynos-usbdrd-eusb.c b/drivers/phy/samsung/phy-exynos-usbdrd-eusb.c
index c98ad2fdf..af4e73e9e 100644
--- a/drivers/phy/samsung/phy-exynos-usbdrd-eusb.c
+++ b/drivers/phy/samsung/phy-exynos-usbdrd-eusb.c
@@ -10,6 +10,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/kvm_host.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -1922,8 +1923,11 @@ int exynos_usbdrd_s2mpu_manual_control(bool on)
if (!phy_drd->s2mpu)
return 0;
- return on ? pm_runtime_get_sync(phy_drd->s2mpu)
- : pm_runtime_put_sync_suspend(phy_drd->s2mpu);
+ if (is_protected_kvm_enabled())
+ return on ? pkvm_iommu_resume(phy_drd->s2mpu)
+ : pkvm_iommu_suspend(phy_drd->s2mpu);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(exynos_usbdrd_s2mpu_manual_control);
diff --git a/drivers/phy/samsung/phy-exynos-usbdrd.c b/drivers/phy/samsung/phy-exynos-usbdrd.c
index 88e74fc4f..9439f64ed 100644
--- a/drivers/phy/samsung/phy-exynos-usbdrd.c
+++ b/drivers/phy/samsung/phy-exynos-usbdrd.c
@@ -18,6 +18,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/kvm_host.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -2093,8 +2094,11 @@ int exynos_usbdrd_s2mpu_manual_control(bool on)
if (!phy_drd->s2mpu)
return 0;
- return on ? pm_runtime_get_sync(phy_drd->s2mpu)
- : pm_runtime_put_sync_suspend(phy_drd->s2mpu);
+ if (is_protected_kvm_enabled())
+ return on ? pkvm_iommu_resume(phy_drd->s2mpu)
+ : pkvm_iommu_suspend(phy_drd->s2mpu);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(exynos_usbdrd_s2mpu_manual_control);