Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/tegra: Move IOMMU group into host1x client

Handling of the IOMMU group attachment is common to all clients, so move
the group into the client to simplify code.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+32 -40
+4 -5
drivers/gpu/drm/tegra/dc.c
··· 2014 2014 if (!dc->syncpt) 2015 2015 dev_warn(dc->dev, "failed to allocate syncpoint\n"); 2016 2016 2017 - dc->group = host1x_client_iommu_attach(client, true); 2018 - if (IS_ERR(dc->group)) { 2019 - err = PTR_ERR(dc->group); 2017 + err = host1x_client_iommu_attach(client, true); 2018 + if (err < 0) { 2020 2019 dev_err(client->dev, "failed to attach to domain: %d\n", err); 2021 2020 return err; 2022 2021 } ··· 2088 2089 if (!IS_ERR(primary)) 2089 2090 drm_plane_cleanup(primary); 2090 2091 2091 - host1x_client_iommu_detach(client, dc->group); 2092 + host1x_client_iommu_detach(client); 2092 2093 host1x_syncpt_free(dc->syncpt); 2093 2094 2094 2095 return err; ··· 2113 2114 return err; 2114 2115 } 2115 2116 2116 - host1x_client_iommu_detach(client, dc->group); 2117 + host1x_client_iommu_detach(client); 2117 2118 host1x_syncpt_free(dc->syncpt); 2118 2119 2119 2120 return 0;
-2
drivers/gpu/drm/tegra/dc.h
··· 90 90 struct drm_info_list *debugfs_files; 91 91 92 92 const struct tegra_dc_soc_info *soc; 93 - 94 - struct iommu_group *group; 95 93 }; 96 94 97 95 static inline struct tegra_dc *
+11 -11
drivers/gpu/drm/tegra/drm.c
··· 1068 1068 return 0; 1069 1069 } 1070 1070 1071 - struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client, 1072 - bool shared) 1071 + int host1x_client_iommu_attach(struct host1x_client *client, bool shared) 1073 1072 { 1074 1073 struct drm_device *drm = dev_get_drvdata(client->parent); 1075 1074 struct tegra_drm *tegra = drm->dev_private; ··· 1079 1080 group = iommu_group_get(client->dev); 1080 1081 if (!group) { 1081 1082 dev_err(client->dev, "failed to get IOMMU group\n"); 1082 - return ERR_PTR(-ENODEV); 1083 + return -ENODEV; 1083 1084 } 1084 1085 1085 1086 if (!shared || (shared && (group != tegra->group))) { ··· 1094 1095 err = iommu_attach_group(tegra->domain, group); 1095 1096 if (err < 0) { 1096 1097 iommu_group_put(group); 1097 - return ERR_PTR(err); 1098 + return err; 1098 1099 } 1099 1100 1100 1101 if (shared && !tegra->group) ··· 1102 1103 } 1103 1104 } 1104 1105 1105 - return group; 1106 + client->group = group; 1107 + 1108 + return 0; 1106 1109 } 1107 1110 1108 - void host1x_client_iommu_detach(struct host1x_client *client, 1109 - struct iommu_group *group) 1111 + void host1x_client_iommu_detach(struct host1x_client *client) 1110 1112 { 1111 1113 struct drm_device *drm = dev_get_drvdata(client->parent); 1112 1114 struct tegra_drm *tegra = drm->dev_private; 1113 1115 1114 - if (group) { 1115 - if (group == tegra->group) { 1116 - iommu_detach_group(tegra->domain, group); 1116 + if (client->group) { 1117 + if (client->group == tegra->group) { 1118 + iommu_detach_group(tegra->domain, client->group); 1117 1119 tegra->group = NULL; 1118 1120 } 1119 1121 1120 - iommu_group_put(group); 1122 + iommu_group_put(client->group); 1121 1123 } 1122 1124 } 1123 1125
+2 -4
drivers/gpu/drm/tegra/drm.h
··· 100 100 struct tegra_drm_client *client); 101 101 int tegra_drm_unregister_client(struct tegra_drm *tegra, 102 102 struct tegra_drm_client *client); 103 - struct iommu_group *host1x_client_iommu_attach(struct host1x_client *client, 104 - bool shared); 105 - void host1x_client_iommu_detach(struct host1x_client *client, 106 - struct iommu_group *group); 103 + int host1x_client_iommu_attach(struct host1x_client *client, bool shared); 104 + void host1x_client_iommu_detach(struct host1x_client *client); 107 105 108 106 int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm); 109 107 int tegra_drm_exit(struct tegra_drm *tegra);
+4 -6
drivers/gpu/drm/tegra/gr2d.c
··· 17 17 }; 18 18 19 19 struct gr2d { 20 - struct iommu_group *group; 21 20 struct tegra_drm_client client; 22 21 struct host1x_channel *channel; 23 22 struct clk *clk; ··· 50 51 goto put; 51 52 } 52 53 53 - gr2d->group = host1x_client_iommu_attach(client, false); 54 - if (IS_ERR(gr2d->group)) { 55 - err = PTR_ERR(gr2d->group); 54 + err = host1x_client_iommu_attach(client, false); 55 + if (err < 0) { 56 56 dev_err(client->dev, "failed to attach to domain: %d\n", err); 57 57 goto free; 58 58 } ··· 65 67 return 0; 66 68 67 69 detach: 68 - host1x_client_iommu_detach(client, gr2d->group); 70 + host1x_client_iommu_detach(client); 69 71 free: 70 72 host1x_syncpt_free(client->syncpts[0]); 71 73 put: ··· 85 87 if (err < 0) 86 88 return err; 87 89 88 - host1x_client_iommu_detach(client, gr2d->group); 90 + host1x_client_iommu_detach(client); 89 91 host1x_syncpt_free(client->syncpts[0]); 90 92 host1x_channel_put(gr2d->channel); 91 93
+4 -6
drivers/gpu/drm/tegra/gr3d.c
··· 23 23 }; 24 24 25 25 struct gr3d { 26 - struct iommu_group *group; 27 26 struct tegra_drm_client client; 28 27 struct host1x_channel *channel; 29 28 struct clk *clk_secondary; ··· 59 60 goto put; 60 61 } 61 62 62 - gr3d->group = host1x_client_iommu_attach(client, false); 63 - if (IS_ERR(gr3d->group)) { 64 - err = PTR_ERR(gr3d->group); 63 + err = host1x_client_iommu_attach(client, false); 64 + if (err < 0) { 65 65 dev_err(client->dev, "failed to attach to domain: %d\n", err); 66 66 goto free; 67 67 } ··· 74 76 return 0; 75 77 76 78 detach: 77 - host1x_client_iommu_detach(client, gr3d->group); 79 + host1x_client_iommu_detach(client); 78 80 free: 79 81 host1x_syncpt_free(client->syncpts[0]); 80 82 put: ··· 93 95 if (err < 0) 94 96 return err; 95 97 96 - host1x_client_iommu_detach(client, gr3d->group); 98 + host1x_client_iommu_detach(client); 97 99 host1x_syncpt_free(client->syncpts[0]); 98 100 host1x_channel_put(gr3d->channel); 99 101
+4 -6
drivers/gpu/drm/tegra/vic.c
··· 34 34 void __iomem *regs; 35 35 struct tegra_drm_client client; 36 36 struct host1x_channel *channel; 37 - struct iommu_group *group; 38 37 struct device *dev; 39 38 struct clk *clk; 40 39 struct reset_control *rst; ··· 187 188 struct vic *vic = to_vic(drm); 188 189 int err; 189 190 190 - vic->group = host1x_client_iommu_attach(client, false); 191 - if (IS_ERR(vic->group)) { 192 - err = PTR_ERR(vic->group); 191 + err = host1x_client_iommu_attach(client, false); 192 + if (err < 0) { 193 193 dev_err(vic->dev, "failed to attach to domain: %d\n", err); 194 194 return err; 195 195 } ··· 222 224 free_channel: 223 225 host1x_channel_put(vic->channel); 224 226 detach: 225 - host1x_client_iommu_detach(client, vic->group); 227 + host1x_client_iommu_detach(client); 226 228 227 229 return err; 228 230 } ··· 244 246 245 247 host1x_syncpt_free(client->syncpts[0]); 246 248 host1x_channel_put(vic->channel); 247 - host1x_client_iommu_detach(client, vic->group); 249 + host1x_client_iommu_detach(client); 248 250 249 251 return 0; 250 252 }
+3
include/linux/host1x.h
··· 18 18 }; 19 19 20 20 struct host1x_client; 21 + struct iommu_group; 21 22 22 23 /** 23 24 * struct host1x_client_ops - host1x client operations ··· 35 34 * @list: list node for the host1x client 36 35 * @parent: pointer to struct device representing the host1x controller 37 36 * @dev: pointer to struct device backing this host1x client 37 + * @group: IOMMU group that this client is a member of 38 38 * @ops: host1x client operations 39 39 * @class: host1x class represented by this client 40 40 * @channel: host1x channel associated with this client ··· 46 44 struct list_head list; 47 45 struct device *parent; 48 46 struct device *dev; 47 + struct iommu_group *group; 49 48 50 49 const struct host1x_client_ops *ops; 51 50