aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna2016-01-25 15:27:44 -0600
committerSuman Anna2019-03-03 17:39:54 -0600
commit4252fc9bc3522b508d3a74b12b8c9a0be1e3d13f (patch)
tree8d1f9be204030cf8b24c773de12373515bbb5c6b
parentd07f2e6c2ade8e7cc32088b095da1db996f0eab5 (diff)
downloadremoteproc-4252fc9bc3522b508d3a74b12b8c9a0be1e3d13f.tar.gz
remoteproc-4252fc9bc3522b508d3a74b12b8c9a0be1e3d13f.tar.xz
remoteproc-4252fc9bc3522b508d3a74b12b8c9a0be1e3d13f.zip
iommu/omap: Add system suspend/resume support
The MMU registers for the remote processors lose their context in Open Switch Retention (OSWR) or device OFF modes. Hence, the context of the IOMMU needs to be saved before it is put into any of these lower power state (OSWR/OFF) and restored before it is powered up to ON again. The IOMMUs need to be active as long as the client devices that are present behind the IOMMU are active. This patch adds the dev_pm_ops callbacks to provide the system suspend/resume functionality through the appropriate runtime PM callbacks. The PM runtime_resume and runtime_suspend callbacks are already used to enable, configure and disable the IOMMUs during the attaching and detaching of the client devices to the IOMMUs, and the new PM callbacks reuse the same code by invoking the pm_runtime_force_suspend() and pm_runtime_force_resume() API. The functionality in dev_pm_ops .prepare() checks if the IOMMU device was already runtime suspended, and skips invoking the suspend/resume PM callbacks. The suspend/resume PM callbacks are plugged in through the 'late' pm ops to ensure that the IOMMU devices will be suspended only after its master devices (remoteproc devices) are suspended and restored before them. NOTE: There are two other existing API, omap_iommu_save_ctx() and omap_iommu_restore_ctx(). These are left as is to support suspend/resume of devices on legacy OMAP3 SoC. Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--drivers/iommu/omap-iommu.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 1042772341e1..eff76edded94 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -69,6 +69,9 @@ static struct omap_iommu_domain *to_omap_domain(struct iommu_domain *dom)
69/** 69/**
70 * omap_iommu_save_ctx - Save registers for pm off-mode support 70 * omap_iommu_save_ctx - Save registers for pm off-mode support
71 * @dev: client device 71 * @dev: client device
72 *
73 * This should be treated as an deprecated API. It is preserved only
74 * to maintain existing functionality for OMAP3 ISP driver.
72 **/ 75 **/
73void omap_iommu_save_ctx(struct device *dev) 76void omap_iommu_save_ctx(struct device *dev)
74{ 77{
@@ -96,6 +99,9 @@ EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);
96/** 99/**
97 * omap_iommu_restore_ctx - Restore registers for pm off-mode support 100 * omap_iommu_restore_ctx - Restore registers for pm off-mode support
98 * @dev: client device 101 * @dev: client device
102 *
103 * This should be treated as an deprecated API. It is preserved only
104 * to maintain existing functionality for OMAP3 ISP driver.
99 **/ 105 **/
100void omap_iommu_restore_ctx(struct device *dev) 106void omap_iommu_restore_ctx(struct device *dev)
101{ 107{
@@ -1025,6 +1031,23 @@ static int omap_iommu_runtime_resume(struct device *dev)
1025 return ret; 1031 return ret;
1026} 1032}
1027 1033
1034/**
1035 * omap_iommu_suspend_prepare - prepare() dev_pm_ops implementation
1036 * @dev: iommu device
1037 *
1038 * This function performs the necessary checks to determine if the IOMMU
1039 * device needs suspending or not. The function checks if the runtime_pm
1040 * status of the device is suspended, and returns 1 in that case. This
1041 * results in the PM core to skip invoking any of the Sleep PM callbacks
1042 * (suspend, suspend_late, resume, resume_early etc).
1043 */
1044static int omap_iommu_prepare(struct device *dev)
1045{
1046 if (pm_runtime_status_suspended(dev))
1047 return 1;
1048 return 0;
1049}
1050
1028static bool omap_iommu_can_register(struct platform_device *pdev) 1051static bool omap_iommu_can_register(struct platform_device *pdev)
1029{ 1052{
1030 struct device_node *np = pdev->dev.of_node; 1053 struct device_node *np = pdev->dev.of_node;
@@ -1202,6 +1225,9 @@ static int omap_iommu_remove(struct platform_device *pdev)
1202} 1225}
1203 1226
1204static const struct dev_pm_ops omap_iommu_pm_ops = { 1227static const struct dev_pm_ops omap_iommu_pm_ops = {
1228 .prepare = omap_iommu_prepare,
1229 SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1230 pm_runtime_force_resume)
1205 SET_RUNTIME_PM_OPS(omap_iommu_runtime_suspend, 1231 SET_RUNTIME_PM_OPS(omap_iommu_runtime_suspend,
1206 omap_iommu_runtime_resume, NULL) 1232 omap_iommu_runtime_resume, NULL)
1207}; 1233};