diff options
author | Suman Anna | 2015-05-17 21:03:33 -0500 |
---|---|---|
committer | Suman Anna | 2015-05-17 21:10:28 -0500 |
commit | 1ded918d1661273cd2f52397a5a3ddd32c82a6f3 (patch) | |
tree | e091561ef56a4291b6d7a9a818d75b8cdd9f6323 | |
parent | 21890c97c9ce94795bcf506c2cb572677c5da8c8 (diff) | |
parent | 25b90cefc9f6fa4c19c9e0462824820ea3940f4e (diff) | |
download | kernel-audio-1ded918d1661273cd2f52397a5a3ddd32c82a6f3.tar.gz kernel-audio-1ded918d1661273cd2f52397a5a3ddd32c82a6f3.tar.xz kernel-audio-1ded918d1661273cd2f52397a5a3ddd32c82a6f3.zip |
Merge branch 'iommu-linux-3.14.y' of git://git.ti.com/rpmsg/iommu into rproc-linux-3.14.y
Merge in the updated iommu feature branch into remoteproc tree to
pull in the suspend/resume support in the OMAP IOMMU driver. The
following are the main changes:
- improvements in the OMAP iommu to perform the enabling &
disabling of the IOMMU from within the runtime pm callbacks
- two new API that needs to be invoked from the OMAP remoteproc
driver to suspend/resume the IOMMU.
- locked TLB save & restore logic
- add needed pdata quirks to all supported IOMMUs
* 'iommu-linux-3.14.y' of git://git.ti.com/rpmsg/iommu:
iommu/omap: add support for runtime auto suspend/resume
iommu/omap: add logic to save/restore locked TLBs
iommu/omap: introduce new API for suspend/resume
iommu/omap: streamline enable/disable through runtime pm callbacks
ARM: OMAP2+: add pdata-quirks for OMAP3 ISP IOMMU
ARM: OMAP2+: Add iommu pdata-quirks for DRA7 DSP EDMA MMUs
ARM: OMAP2+: plug in device_enable/idle ops for IOMMUs
iommu/omap: add pdata ops for omap_device_enable/idle
Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/omap-iommu.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pdata-quirks.c | 20 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.c | 247 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.h | 3 | ||||
-rw-r--r-- | include/linux/omap-iommu.h | 3 | ||||
-rw-r--r-- | include/linux/platform_data/iommu-omap.h | 2 |
6 files changed, 254 insertions, 23 deletions
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index f1fab5684a24..d6803a41034c 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c | |||
@@ -42,6 +42,8 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused) | |||
42 | pdata->assert_reset = omap_device_assert_hardreset; | 42 | pdata->assert_reset = omap_device_assert_hardreset; |
43 | pdata->deassert_reset = omap_device_deassert_hardreset; | 43 | pdata->deassert_reset = omap_device_deassert_hardreset; |
44 | } | 44 | } |
45 | pdata->device_enable = omap_device_enable, | ||
46 | pdata->device_idle = omap_device_idle, | ||
45 | 47 | ||
46 | pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata)); | 48 | pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata)); |
47 | 49 | ||
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index bce029f1bdcd..9bb61bec9251 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c | |||
@@ -89,6 +89,13 @@ static struct iommu_platform_data omap3_iommu_pdata = { | |||
89 | .reset_name = "mmu", | 89 | .reset_name = "mmu", |
90 | .assert_reset = omap_device_assert_hardreset, | 90 | .assert_reset = omap_device_assert_hardreset, |
91 | .deassert_reset = omap_device_deassert_hardreset, | 91 | .deassert_reset = omap_device_deassert_hardreset, |
92 | .device_enable = omap_device_enable, | ||
93 | .device_idle = omap_device_idle, | ||
94 | }; | ||
95 | |||
96 | static struct iommu_platform_data omap3_iommu_isp_pdata = { | ||
97 | .device_enable = omap_device_enable, | ||
98 | .device_idle = omap_device_idle, | ||
92 | }; | 99 | }; |
93 | 100 | ||
94 | static int omap3_sbc_t3730_twl_callback(struct device *dev, | 101 | static int omap3_sbc_t3730_twl_callback(struct device *dev, |
@@ -221,6 +228,8 @@ static struct iommu_platform_data omap4_iommu_pdata = { | |||
221 | .reset_name = "mmu_cache", | 228 | .reset_name = "mmu_cache", |
222 | .assert_reset = omap_device_assert_hardreset, | 229 | .assert_reset = omap_device_assert_hardreset, |
223 | .deassert_reset = omap_device_deassert_hardreset, | 230 | .deassert_reset = omap_device_deassert_hardreset, |
231 | .device_enable = omap_device_enable, | ||
232 | .device_idle = omap_device_idle, | ||
224 | }; | 233 | }; |
225 | 234 | ||
226 | static struct omap_rproc_pdata omap4_ipu_pdata = { | 235 | static struct omap_rproc_pdata omap4_ipu_pdata = { |
@@ -240,6 +249,11 @@ static struct omap_rproc_pdata omap4_dsp_pdata = { | |||
240 | #endif | 249 | #endif |
241 | 250 | ||
242 | #ifdef CONFIG_SOC_DRA7XX | 251 | #ifdef CONFIG_SOC_DRA7XX |
252 | static struct iommu_platform_data dra7_dsp_mmu_edma_pdata = { | ||
253 | .device_enable = omap_device_enable, | ||
254 | .device_idle = omap_device_idle, | ||
255 | }; | ||
256 | |||
243 | static struct omap_rproc_pdata dra7_dsp1_pdata = { | 257 | static struct omap_rproc_pdata dra7_dsp1_pdata = { |
244 | .device_enable = omap_rproc_device_enable, | 258 | .device_enable = omap_rproc_device_enable, |
245 | .device_shutdown = omap_rproc_device_shutdown, | 259 | .device_shutdown = omap_rproc_device_shutdown, |
@@ -317,6 +331,8 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { | |||
317 | OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata), | 331 | OF_DEV_AUXDATA("ti,omap3-padconf", 0x48002a00, "48002a00.pinmux", &pcs_pdata), |
318 | OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu", | 332 | OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu", |
319 | &omap3_iommu_pdata), | 333 | &omap3_iommu_pdata), |
334 | OF_DEV_AUXDATA("ti,omap2-iommu", 0x480bd400, "480bd400.mmu", | ||
335 | &omap3_iommu_isp_pdata), | ||
320 | /* Only on am3517 */ | 336 | /* Only on am3517 */ |
321 | OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), | 337 | OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), |
322 | OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", | 338 | OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", |
@@ -353,8 +369,12 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { | |||
353 | OF_DEV_AUXDATA("ti,dra7-padconf", 0x4a003400, "4a003400.pinmux", &pcs_pdata), | 369 | OF_DEV_AUXDATA("ti,dra7-padconf", 0x4a003400, "4a003400.pinmux", &pcs_pdata), |
354 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x40d01000, "40d01000.mmu", | 370 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x40d01000, "40d01000.mmu", |
355 | &omap4_iommu_pdata), | 371 | &omap4_iommu_pdata), |
372 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x40d02000, "40d02000.mmu", | ||
373 | &dra7_dsp_mmu_edma_pdata), | ||
356 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x41501000, "41501000.mmu", | 374 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x41501000, "41501000.mmu", |
357 | &omap4_iommu_pdata), | 375 | &omap4_iommu_pdata), |
376 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x41502000, "41502000.mmu", | ||
377 | &dra7_dsp_mmu_edma_pdata), | ||
358 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x55082000, "55082000.mmu", | 378 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x55082000, "55082000.mmu", |
359 | &omap4_iommu_pdata), | 379 | &omap4_iommu_pdata), |
360 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu", | 380 | OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu", |
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 693f23c46a64..17b7890616b2 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -129,6 +129,11 @@ EXPORT_SYMBOL_GPL(omap_uninstall_iommu_arch); | |||
129 | /** | 129 | /** |
130 | * omap_iommu_save_ctx - Save registers for pm off-mode support | 130 | * omap_iommu_save_ctx - Save registers for pm off-mode support |
131 | * @dev: client device | 131 | * @dev: client device |
132 | * | ||
133 | * This should be treated as an deprecated API. It is preserved only | ||
134 | * to maintain existing functionality for OMAP3 ISP driver, newer | ||
135 | * SoCs will leverage the newer omap_iommu_domain_suspend() API and | ||
136 | * associated runtime_suspend callback. | ||
132 | **/ | 137 | **/ |
133 | void omap_iommu_save_ctx(struct device *dev) | 138 | void omap_iommu_save_ctx(struct device *dev) |
134 | { | 139 | { |
@@ -146,6 +151,11 @@ EXPORT_SYMBOL_GPL(omap_iommu_save_ctx); | |||
146 | /** | 151 | /** |
147 | * omap_iommu_restore_ctx - Restore registers for pm off-mode support | 152 | * omap_iommu_restore_ctx - Restore registers for pm off-mode support |
148 | * @dev: client device | 153 | * @dev: client device |
154 | * | ||
155 | * This should be treated as an deprecated API. It is preserved only | ||
156 | * to maintain existing functionality for OMAP3 ISP driver, newer | ||
157 | * SoCs will leverage the newer omap_iommu_domain_resume() API and | ||
158 | * associated runtime_resume callback. | ||
149 | **/ | 159 | **/ |
150 | void omap_iommu_restore_ctx(struct device *dev) | 160 | void omap_iommu_restore_ctx(struct device *dev) |
151 | { | 161 | { |
@@ -162,39 +172,24 @@ EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx); | |||
162 | 172 | ||
163 | static int iommu_enable(struct omap_iommu *obj) | 173 | static int iommu_enable(struct omap_iommu *obj) |
164 | { | 174 | { |
165 | int err; | 175 | int ret; |
166 | struct platform_device *pdev = to_platform_device(obj->dev); | ||
167 | struct iommu_platform_data *pdata = pdev->dev.platform_data; | ||
168 | 176 | ||
169 | if (!arch_iommu) | 177 | if (!arch_iommu) |
170 | return -ENODEV; | 178 | return -ENODEV; |
171 | 179 | ||
172 | if (pdata && pdata->deassert_reset) { | 180 | ret = pm_runtime_get_sync(obj->dev); |
173 | err = pdata->deassert_reset(pdev, pdata->reset_name); | 181 | if (ret < 0) |
174 | if (err) { | 182 | pm_runtime_put_noidle(obj->dev); |
175 | dev_err(obj->dev, "deassert_reset failed: %d\n", err); | ||
176 | return err; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | pm_runtime_get_sync(obj->dev); | ||
181 | |||
182 | err = arch_iommu->enable(obj); | ||
183 | 183 | ||
184 | return err; | 184 | return ret < 0 ? ret : 0; |
185 | } | 185 | } |
186 | 186 | ||
187 | static void iommu_disable(struct omap_iommu *obj) | 187 | static void iommu_disable(struct omap_iommu *obj) |
188 | { | 188 | { |
189 | struct platform_device *pdev = to_platform_device(obj->dev); | 189 | if (!arch_iommu) |
190 | struct iommu_platform_data *pdata = pdev->dev.platform_data; | 190 | return; |
191 | |||
192 | arch_iommu->disable(obj); | ||
193 | 191 | ||
194 | pm_runtime_put_sync(obj->dev); | 192 | pm_runtime_put_sync(obj->dev); |
195 | |||
196 | if (pdata && pdata->assert_reset) | ||
197 | pdata->assert_reset(pdev, pdata->reset_name); | ||
198 | } | 193 | } |
199 | 194 | ||
200 | /* | 195 | /* |
@@ -913,14 +908,200 @@ static void omap_iommu_detach(struct omap_iommu *obj) | |||
913 | 908 | ||
914 | spin_lock(&obj->iommu_lock); | 909 | spin_lock(&obj->iommu_lock); |
915 | 910 | ||
916 | iommu_disable(obj); | ||
917 | obj->iopgd = NULL; | 911 | obj->iopgd = NULL; |
912 | iommu_disable(obj); | ||
918 | 913 | ||
919 | spin_unlock(&obj->iommu_lock); | 914 | spin_unlock(&obj->iommu_lock); |
920 | 915 | ||
921 | dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name); | 916 | dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name); |
922 | } | 917 | } |
923 | 918 | ||
919 | /** | ||
920 | * omap_iommu_domain_suspend - suspend the iommu device | ||
921 | * @domain: iommu domain attached to the target iommu device | ||
922 | * @auto_suspend: flag to indicate system suspend or runtime suspend | ||
923 | * | ||
924 | * This API allows the client devices of IOMMU devices to suspend | ||
925 | * the IOMMUs they control, after they are idled and suspended all | ||
926 | * activity. | ||
927 | **/ | ||
928 | int omap_iommu_domain_suspend(struct iommu_domain *domain, bool auto_suspend) | ||
929 | { | ||
930 | struct omap_iommu_domain *omap_domain = domain->priv; | ||
931 | struct omap_iommu_device *iommu; | ||
932 | struct omap_iommu *oiommu; | ||
933 | int i; | ||
934 | |||
935 | if (!omap_domain->attached) | ||
936 | return 0; | ||
937 | |||
938 | iommu = omap_domain->iommus; | ||
939 | iommu += (omap_domain->num_iommus - 1); | ||
940 | for (i = 0; i < omap_domain->num_iommus; i++, iommu--) { | ||
941 | oiommu = iommu->iommu_dev; | ||
942 | if (auto_suspend) { | ||
943 | pm_runtime_put_sync(oiommu->dev); | ||
944 | } else { | ||
945 | pm_runtime_put_noidle(oiommu->dev); | ||
946 | pm_generic_runtime_suspend(oiommu->dev); | ||
947 | pm_runtime_disable(oiommu->dev); | ||
948 | pm_runtime_set_suspended(oiommu->dev); | ||
949 | } | ||
950 | } | ||
951 | |||
952 | return 0; | ||
953 | } | ||
954 | EXPORT_SYMBOL_GPL(omap_iommu_domain_suspend); | ||
955 | |||
956 | /** | ||
957 | * omap_iommu_domain_resume - resume the iommu device | ||
958 | * @domain: iommu domain attached to the target iommu device | ||
959 | * @auto_suspend: flag to indicate system suspend or runtime suspend | ||
960 | * | ||
961 | * This API allows the client devices of IOMMU devices to resume | ||
962 | * the IOMMUs they control, before they can resume operations. | ||
963 | **/ | ||
964 | int omap_iommu_domain_resume(struct iommu_domain *domain, bool auto_suspend) | ||
965 | { | ||
966 | struct omap_iommu_domain *omap_domain = domain->priv; | ||
967 | struct omap_iommu_device *iommu; | ||
968 | struct omap_iommu *oiommu; | ||
969 | int i; | ||
970 | |||
971 | if (!omap_domain->attached) | ||
972 | return 0; | ||
973 | |||
974 | iommu = omap_domain->iommus; | ||
975 | for (i = 0; i < omap_domain->num_iommus; i++, iommu++) { | ||
976 | oiommu = iommu->iommu_dev; | ||
977 | if (auto_suspend) { | ||
978 | pm_runtime_get_sync(oiommu->dev); | ||
979 | } else { | ||
980 | pm_runtime_set_active(oiommu->dev); | ||
981 | pm_runtime_enable(oiommu->dev); | ||
982 | pm_runtime_get_noresume(oiommu->dev); | ||
983 | pm_generic_runtime_resume(oiommu->dev); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | EXPORT_SYMBOL_GPL(omap_iommu_domain_resume); | ||
990 | |||
991 | static void omap_iommu_save_tlb_entries(struct omap_iommu *obj) | ||
992 | { | ||
993 | struct iotlb_lock lock; | ||
994 | struct cr_regs cr; | ||
995 | struct cr_regs *tmp; | ||
996 | int i; | ||
997 | |||
998 | /* check if there are any locked tlbs to save */ | ||
999 | iotlb_lock_get(obj, &lock); | ||
1000 | obj->num_cr_ctx = lock.base; | ||
1001 | if (!obj->num_cr_ctx) | ||
1002 | return; | ||
1003 | |||
1004 | tmp = obj->cr_ctx; | ||
1005 | for_each_iotlb_cr(obj, obj->num_cr_ctx, i, cr) | ||
1006 | *tmp++ = cr; | ||
1007 | } | ||
1008 | |||
1009 | static void omap_iommu_restore_tlb_entries(struct omap_iommu *obj) | ||
1010 | { | ||
1011 | struct iotlb_lock l; | ||
1012 | struct cr_regs *tmp; | ||
1013 | int i; | ||
1014 | |||
1015 | /* no locked tlbs to restore */ | ||
1016 | if (!obj->num_cr_ctx) | ||
1017 | return; | ||
1018 | |||
1019 | l.base = 0; | ||
1020 | tmp = obj->cr_ctx; | ||
1021 | for (i = 0; i < obj->num_cr_ctx; i++, tmp++) { | ||
1022 | l.vict = i; | ||
1023 | iotlb_lock_set(obj, &l); | ||
1024 | iotlb_load_cr(obj, tmp); | ||
1025 | } | ||
1026 | l.base = obj->num_cr_ctx; | ||
1027 | l.vict = i; | ||
1028 | iotlb_lock_set(obj, &l); | ||
1029 | } | ||
1030 | |||
1031 | /** | ||
1032 | * omap_iommu_runtime_suspend - disable an iommu device | ||
1033 | * @dev: iommu device | ||
1034 | * | ||
1035 | * This function performs all that is necessary to disable an | ||
1036 | * IOMMU device, either during final detachment from a client | ||
1037 | * device, or during system/runtime suspend of the device. This | ||
1038 | * includes programming all the appropriate IOMMU registers, and | ||
1039 | * managing the associated omap_hwmod's state and the device's | ||
1040 | * reset line. This function also saves the context of any | ||
1041 | * locked TLBs if suspending. | ||
1042 | **/ | ||
1043 | static int omap_iommu_runtime_suspend(struct device *dev) | ||
1044 | { | ||
1045 | struct platform_device *pdev = to_platform_device(dev); | ||
1046 | struct iommu_platform_data *pdata = dev_get_platdata(dev); | ||
1047 | struct omap_iommu *obj = to_iommu(dev); | ||
1048 | |||
1049 | /* save the TLBs only during suspend, and not for power down */ | ||
1050 | if (obj->domain && obj->iopgd) | ||
1051 | omap_iommu_save_tlb_entries(obj); | ||
1052 | |||
1053 | if (arch_iommu->disable) | ||
1054 | arch_iommu->disable(obj); | ||
1055 | |||
1056 | if (pdata && pdata->device_idle) | ||
1057 | pdata->device_idle(pdev); | ||
1058 | |||
1059 | if (pdata && pdata->assert_reset) | ||
1060 | pdata->assert_reset(pdev, pdata->reset_name); | ||
1061 | |||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | /** | ||
1066 | * omap_iommu_runtime_resume - enable an iommu device | ||
1067 | * @dev: iommu device | ||
1068 | * | ||
1069 | * This function performs all that is necessary to enable an | ||
1070 | * IOMMU device, either during initial attachment to a client | ||
1071 | * device, or during system/runtime resume of the device. This | ||
1072 | * includes programming all the appropriate IOMMU registers, and | ||
1073 | * managing the associated omap_hwmod's state and the device's | ||
1074 | * reset line. The function also restores any locked TLBs if | ||
1075 | * resuming after a suspend. | ||
1076 | **/ | ||
1077 | static int omap_iommu_runtime_resume(struct device *dev) | ||
1078 | { | ||
1079 | struct platform_device *pdev = to_platform_device(dev); | ||
1080 | struct iommu_platform_data *pdata = dev_get_platdata(dev); | ||
1081 | struct omap_iommu *obj = to_iommu(dev); | ||
1082 | int ret = 0; | ||
1083 | |||
1084 | if (pdata && pdata->deassert_reset) { | ||
1085 | ret = pdata->deassert_reset(pdev, pdata->reset_name); | ||
1086 | if (ret) { | ||
1087 | dev_err(dev, "deassert_reset failed: %d\n", ret); | ||
1088 | return ret; | ||
1089 | } | ||
1090 | } | ||
1091 | |||
1092 | if (pdata && pdata->device_enable) | ||
1093 | pdata->device_enable(pdev); | ||
1094 | |||
1095 | /* restore the TLBs only during resume, and not for power up */ | ||
1096 | if (obj->domain) | ||
1097 | omap_iommu_restore_tlb_entries(obj); | ||
1098 | |||
1099 | if (arch_iommu->enable) | ||
1100 | ret = arch_iommu->enable(obj); | ||
1101 | |||
1102 | return ret; | ||
1103 | } | ||
1104 | |||
924 | static int omap_iommu_dra7_get_dsp_system_cfg(struct platform_device *pdev, | 1105 | static int omap_iommu_dra7_get_dsp_system_cfg(struct platform_device *pdev, |
925 | struct omap_iommu *obj, | 1106 | struct omap_iommu *obj, |
926 | resource_size_t start) | 1107 | resource_size_t start) |
@@ -977,6 +1158,15 @@ static int omap_iommu_probe(struct platform_device *pdev) | |||
977 | if (!obj) | 1158 | if (!obj) |
978 | return -ENOMEM; | 1159 | return -ENOMEM; |
979 | 1160 | ||
1161 | /* | ||
1162 | * self-manage the ordering dependencies between omap_device_enable/idle | ||
1163 | * and omap_device_assert/deassert_hardreset API | ||
1164 | */ | ||
1165 | if (pdev->dev.pm_domain) { | ||
1166 | dev_dbg(&pdev->dev, "device pm_domain is being reset\n"); | ||
1167 | pdev->dev.pm_domain = NULL; | ||
1168 | } | ||
1169 | |||
980 | if (of) { | 1170 | if (of) { |
981 | obj->name = dev_name(&pdev->dev); | 1171 | obj->name = dev_name(&pdev->dev); |
982 | obj->nr_tlb_entries = 32; | 1172 | obj->nr_tlb_entries = 32; |
@@ -1006,6 +1196,11 @@ static int omap_iommu_probe(struct platform_device *pdev) | |||
1006 | 1196 | ||
1007 | obj->dev = &pdev->dev; | 1197 | obj->dev = &pdev->dev; |
1008 | obj->ctx = (void *)obj + sizeof(*obj); | 1198 | obj->ctx = (void *)obj + sizeof(*obj); |
1199 | obj->cr_ctx = devm_kzalloc(&pdev->dev, | ||
1200 | sizeof(*obj->cr_ctx) * obj->nr_tlb_entries, | ||
1201 | GFP_KERNEL); | ||
1202 | if (!obj->cr_ctx) | ||
1203 | return -ENOMEM; | ||
1009 | 1204 | ||
1010 | spin_lock_init(&obj->iommu_lock); | 1205 | spin_lock_init(&obj->iommu_lock); |
1011 | mutex_init(&obj->mmap_lock); | 1206 | mutex_init(&obj->mmap_lock); |
@@ -1050,6 +1245,11 @@ static int omap_iommu_remove(struct platform_device *pdev) | |||
1050 | return 0; | 1245 | return 0; |
1051 | } | 1246 | } |
1052 | 1247 | ||
1248 | static const struct dev_pm_ops omap_iommu_pm_ops = { | ||
1249 | SET_RUNTIME_PM_OPS(omap_iommu_runtime_suspend, | ||
1250 | omap_iommu_runtime_resume, NULL) | ||
1251 | }; | ||
1252 | |||
1053 | static struct of_device_id omap_iommu_of_match[] = { | 1253 | static struct of_device_id omap_iommu_of_match[] = { |
1054 | { .compatible = "ti,omap2-iommu" }, | 1254 | { .compatible = "ti,omap2-iommu" }, |
1055 | { .compatible = "ti,omap4-iommu" }, | 1255 | { .compatible = "ti,omap4-iommu" }, |
@@ -1063,6 +1263,7 @@ static struct platform_driver omap_iommu_driver = { | |||
1063 | .remove = omap_iommu_remove, | 1263 | .remove = omap_iommu_remove, |
1064 | .driver = { | 1264 | .driver = { |
1065 | .name = "omap-iommu", | 1265 | .name = "omap-iommu", |
1266 | .pm = &omap_iommu_pm_ops, | ||
1066 | .of_match_table = of_match_ptr(omap_iommu_of_match), | 1267 | .of_match_table = of_match_ptr(omap_iommu_of_match), |
1067 | }, | 1268 | }, |
1068 | }; | 1269 | }; |
diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h index c1c0d824c79b..4278aa36b770 100644 --- a/drivers/iommu/omap-iommu.h +++ b/drivers/iommu/omap-iommu.h | |||
@@ -55,6 +55,9 @@ struct omap_iommu { | |||
55 | u32 da_start; | 55 | u32 da_start; |
56 | u32 da_end; | 56 | u32 da_end; |
57 | 57 | ||
58 | struct cr_regs *cr_ctx; | ||
59 | u32 num_cr_ctx; | ||
60 | |||
58 | int has_bus_err_back; | 61 | int has_bus_err_back; |
59 | u32 id; | 62 | u32 id; |
60 | }; | 63 | }; |
diff --git a/include/linux/omap-iommu.h b/include/linux/omap-iommu.h index cac78de09c07..7a3a9c88f163 100644 --- a/include/linux/omap-iommu.h +++ b/include/linux/omap-iommu.h | |||
@@ -49,4 +49,7 @@ extern void *omap_da_to_va(struct device *dev, u32 da); | |||
49 | extern void omap_iommu_save_ctx(struct device *dev); | 49 | extern void omap_iommu_save_ctx(struct device *dev); |
50 | extern void omap_iommu_restore_ctx(struct device *dev); | 50 | extern void omap_iommu_restore_ctx(struct device *dev); |
51 | 51 | ||
52 | int omap_iommu_domain_suspend(struct iommu_domain *domain, bool auto_suspend); | ||
53 | int omap_iommu_domain_resume(struct iommu_domain *domain, bool auto_suspend); | ||
54 | |||
52 | #endif | 55 | #endif |
diff --git a/include/linux/platform_data/iommu-omap.h b/include/linux/platform_data/iommu-omap.h index 5b429c43a297..8aec9172822c 100644 --- a/include/linux/platform_data/iommu-omap.h +++ b/include/linux/platform_data/iommu-omap.h | |||
@@ -51,4 +51,6 @@ struct iommu_platform_data { | |||
51 | 51 | ||
52 | int (*assert_reset)(struct platform_device *pdev, const char *name); | 52 | int (*assert_reset)(struct platform_device *pdev, const char *name); |
53 | int (*deassert_reset)(struct platform_device *pdev, const char *name); | 53 | int (*deassert_reset)(struct platform_device *pdev, const char *name); |
54 | int (*device_enable)(struct platform_device *pdev); | ||
55 | int (*device_idle)(struct platform_device *pdev); | ||
54 | }; | 56 | }; |