diff options
-rw-r--r-- | drivers/iommu/exynos-iommu.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index f596fcc32898..91c548d49b92 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c | |||
@@ -263,6 +263,7 @@ struct exynos_iommu_domain { | |||
263 | struct sysmmu_drvdata { | 263 | struct sysmmu_drvdata { |
264 | struct device *sysmmu; /* SYSMMU controller device */ | 264 | struct device *sysmmu; /* SYSMMU controller device */ |
265 | struct device *master; /* master device (owner) */ | 265 | struct device *master; /* master device (owner) */ |
266 | struct device_link *link; /* runtime PM link to master */ | ||
266 | void __iomem *sfrbase; /* our registers */ | 267 | void __iomem *sfrbase; /* our registers */ |
267 | struct clk *clk; /* SYSMMU's clock */ | 268 | struct clk *clk; /* SYSMMU's clock */ |
268 | struct clk *aclk; /* SYSMMU's aclk clock */ | 269 | struct clk *aclk; /* SYSMMU's aclk clock */ |
@@ -1250,6 +1251,8 @@ static struct iommu_group *get_device_iommu_group(struct device *dev) | |||
1250 | 1251 | ||
1251 | static int exynos_iommu_add_device(struct device *dev) | 1252 | static int exynos_iommu_add_device(struct device *dev) |
1252 | { | 1253 | { |
1254 | struct exynos_iommu_owner *owner = dev->archdata.iommu; | ||
1255 | struct sysmmu_drvdata *data; | ||
1253 | struct iommu_group *group; | 1256 | struct iommu_group *group; |
1254 | 1257 | ||
1255 | if (!has_sysmmu(dev)) | 1258 | if (!has_sysmmu(dev)) |
@@ -1260,6 +1263,15 @@ static int exynos_iommu_add_device(struct device *dev) | |||
1260 | if (IS_ERR(group)) | 1263 | if (IS_ERR(group)) |
1261 | return PTR_ERR(group); | 1264 | return PTR_ERR(group); |
1262 | 1265 | ||
1266 | list_for_each_entry(data, &owner->controllers, owner_node) { | ||
1267 | /* | ||
1268 | * SYSMMU will be runtime activated via device link | ||
1269 | * (dependency) to its master device, so there are no | ||
1270 | * direct calls to pm_runtime_get/put in this driver. | ||
1271 | */ | ||
1272 | data->link = device_link_add(dev, data->sysmmu, | ||
1273 | DL_FLAG_PM_RUNTIME); | ||
1274 | } | ||
1263 | iommu_group_put(group); | 1275 | iommu_group_put(group); |
1264 | 1276 | ||
1265 | return 0; | 1277 | return 0; |
@@ -1268,6 +1280,7 @@ static int exynos_iommu_add_device(struct device *dev) | |||
1268 | static void exynos_iommu_remove_device(struct device *dev) | 1280 | static void exynos_iommu_remove_device(struct device *dev) |
1269 | { | 1281 | { |
1270 | struct exynos_iommu_owner *owner = dev->archdata.iommu; | 1282 | struct exynos_iommu_owner *owner = dev->archdata.iommu; |
1283 | struct sysmmu_drvdata *data; | ||
1271 | 1284 | ||
1272 | if (!has_sysmmu(dev)) | 1285 | if (!has_sysmmu(dev)) |
1273 | return; | 1286 | return; |
@@ -1283,6 +1296,9 @@ static void exynos_iommu_remove_device(struct device *dev) | |||
1283 | } | 1296 | } |
1284 | } | 1297 | } |
1285 | iommu_group_remove_device(dev); | 1298 | iommu_group_remove_device(dev); |
1299 | |||
1300 | list_for_each_entry(data, &owner->controllers, owner_node) | ||
1301 | device_link_del(data->link); | ||
1286 | } | 1302 | } |
1287 | 1303 | ||
1288 | static int exynos_iommu_of_xlate(struct device *dev, | 1304 | static int exynos_iommu_of_xlate(struct device *dev, |
@@ -1316,13 +1332,6 @@ static int exynos_iommu_of_xlate(struct device *dev, | |||
1316 | list_add_tail(&data->owner_node, &owner->controllers); | 1332 | list_add_tail(&data->owner_node, &owner->controllers); |
1317 | data->master = dev; | 1333 | data->master = dev; |
1318 | 1334 | ||
1319 | /* | ||
1320 | * SYSMMU will be runtime activated via device link (dependency) to its | ||
1321 | * master device, so there are no direct calls to pm_runtime_get/put | ||
1322 | * in this driver. | ||
1323 | */ | ||
1324 | device_link_add(dev, data->sysmmu, DL_FLAG_PM_RUNTIME); | ||
1325 | |||
1326 | return 0; | 1335 | return 0; |
1327 | } | 1336 | } |
1328 | 1337 | ||