Commit 53fa7f7204c97dc0c86b99ff8365ad6a7b2ebd78
1 parent
e1e906448d
Exists in
master
and in
16 other branches
drm/tegra: Introduce tegra_drm_client structure
This structure derives from host1x_client. DRM-specific fields are moved from host1x_client to this structure, so that host1x_client can remain agnostic of DRM. Signed-off-by: Thierry Reding <treding@nvidia.com>
Showing 6 changed files with 114 additions and 83 deletions Side-by-side Diff
drivers/gpu/host1x/drm/dc.c
... | ... | @@ -1038,30 +1038,30 @@ |
1038 | 1038 | return 0; |
1039 | 1039 | } |
1040 | 1040 | |
1041 | -static int tegra_dc_drm_init(struct host1x_client *client, | |
1042 | - struct drm_device *drm) | |
1041 | +static int tegra_dc_init(struct host1x_client *client) | |
1043 | 1042 | { |
1044 | - struct tegra_dc *dc = host1x_client_to_dc(client); | |
1043 | + struct tegra_drm_client *drm = to_tegra_drm_client(client); | |
1044 | + struct tegra_dc *dc = tegra_drm_client_to_dc(drm); | |
1045 | 1045 | int err; |
1046 | 1046 | |
1047 | - dc->pipe = drm->mode_config.num_crtc; | |
1047 | + dc->pipe = drm->drm->mode_config.num_crtc; | |
1048 | 1048 | |
1049 | - drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs); | |
1049 | + drm_crtc_init(drm->drm, &dc->base, &tegra_crtc_funcs); | |
1050 | 1050 | drm_mode_crtc_set_gamma_size(&dc->base, 256); |
1051 | 1051 | drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); |
1052 | 1052 | |
1053 | - err = tegra_dc_rgb_init(drm, dc); | |
1053 | + err = tegra_dc_rgb_init(drm->drm, dc); | |
1054 | 1054 | if (err < 0 && err != -ENODEV) { |
1055 | 1055 | dev_err(dc->dev, "failed to initialize RGB output: %d\n", err); |
1056 | 1056 | return err; |
1057 | 1057 | } |
1058 | 1058 | |
1059 | - err = tegra_dc_add_planes(drm, dc); | |
1059 | + err = tegra_dc_add_planes(drm->drm, dc); | |
1060 | 1060 | if (err < 0) |
1061 | 1061 | return err; |
1062 | 1062 | |
1063 | 1063 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { |
1064 | - err = tegra_dc_debugfs_init(dc, drm->primary); | |
1064 | + err = tegra_dc_debugfs_init(dc, drm->drm->primary); | |
1065 | 1065 | if (err < 0) |
1066 | 1066 | dev_err(dc->dev, "debugfs setup failed: %d\n", err); |
1067 | 1067 | } |
1068 | 1068 | |
... | ... | @@ -1077,9 +1077,10 @@ |
1077 | 1077 | return 0; |
1078 | 1078 | } |
1079 | 1079 | |
1080 | -static int tegra_dc_drm_exit(struct host1x_client *client) | |
1080 | +static int tegra_dc_exit(struct host1x_client *client) | |
1081 | 1081 | { |
1082 | - struct tegra_dc *dc = host1x_client_to_dc(client); | |
1082 | + struct tegra_drm_client *drm = to_tegra_drm_client(client); | |
1083 | + struct tegra_dc *dc = tegra_drm_client_to_dc(drm); | |
1083 | 1084 | int err; |
1084 | 1085 | |
1085 | 1086 | devm_free_irq(dc->dev, dc->irq, dc); |
... | ... | @@ -1100,8 +1101,8 @@ |
1100 | 1101 | } |
1101 | 1102 | |
1102 | 1103 | static const struct host1x_client_ops dc_client_ops = { |
1103 | - .drm_init = tegra_dc_drm_init, | |
1104 | - .drm_exit = tegra_dc_drm_exit, | |
1104 | + .init = tegra_dc_init, | |
1105 | + .exit = tegra_dc_exit, | |
1105 | 1106 | }; |
1106 | 1107 | |
1107 | 1108 | static int tegra_dc_probe(struct platform_device *pdev) |
... | ... | @@ -1140,9 +1141,9 @@ |
1140 | 1141 | return -ENXIO; |
1141 | 1142 | } |
1142 | 1143 | |
1143 | - INIT_LIST_HEAD(&dc->client.list); | |
1144 | - dc->client.ops = &dc_client_ops; | |
1145 | - dc->client.dev = &pdev->dev; | |
1144 | + INIT_LIST_HEAD(&dc->client.base.list); | |
1145 | + dc->client.base.ops = &dc_client_ops; | |
1146 | + dc->client.base.dev = &pdev->dev; | |
1146 | 1147 | |
1147 | 1148 | err = tegra_dc_rgb_probe(dc); |
1148 | 1149 | if (err < 0 && err != -ENODEV) { |
... | ... | @@ -1150,7 +1151,7 @@ |
1150 | 1151 | return err; |
1151 | 1152 | } |
1152 | 1153 | |
1153 | - err = host1x_register_client(tegra, &dc->client); | |
1154 | + err = host1x_register_client(tegra, &dc->client.base); | |
1154 | 1155 | if (err < 0) { |
1155 | 1156 | dev_err(&pdev->dev, "failed to register host1x client: %d\n", |
1156 | 1157 | err); |
... | ... | @@ -1168,7 +1169,7 @@ |
1168 | 1169 | struct tegra_dc *dc = platform_get_drvdata(pdev); |
1169 | 1170 | int err; |
1170 | 1171 | |
1171 | - err = host1x_unregister_client(tegra, &dc->client); | |
1172 | + err = host1x_unregister_client(tegra, &dc->client.base); | |
1172 | 1173 | if (err < 0) { |
1173 | 1174 | dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", |
1174 | 1175 | err); |
drivers/gpu/host1x/drm/drm.c
... | ... | @@ -131,12 +131,18 @@ |
131 | 131 | int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm) |
132 | 132 | { |
133 | 133 | struct host1x_client *client; |
134 | + int err; | |
134 | 135 | |
135 | 136 | mutex_lock(&tegra->clients_lock); |
136 | 137 | |
137 | 138 | list_for_each_entry(client, &tegra->clients, list) { |
138 | - if (client->ops && client->ops->drm_init) { | |
139 | - int err = client->ops->drm_init(client, drm); | |
139 | + struct tegra_drm_client *tdc = to_tegra_drm_client(client); | |
140 | + | |
141 | + /* associate client with DRM device */ | |
142 | + tdc->drm = drm; | |
143 | + | |
144 | + if (client->ops && client->ops->init) { | |
145 | + err = client->ops->init(client); | |
140 | 146 | if (err < 0) { |
141 | 147 | dev_err(tegra->dev, |
142 | 148 | "DRM setup failed for %s: %d\n", |
143 | 149 | |
... | ... | @@ -154,8 +160,9 @@ |
154 | 160 | |
155 | 161 | int tegra_drm_exit(struct tegra_drm *tegra) |
156 | 162 | { |
157 | - struct platform_device *pdev = to_platform_device(tegra->dev); | |
158 | 163 | struct host1x_client *client; |
164 | + struct platform_device *pdev; | |
165 | + int err; | |
159 | 166 | |
160 | 167 | if (!tegra->drm) |
161 | 168 | return 0; |
... | ... | @@ -163,8 +170,8 @@ |
163 | 170 | mutex_lock(&tegra->clients_lock); |
164 | 171 | |
165 | 172 | list_for_each_entry_reverse(client, &tegra->clients, list) { |
166 | - if (client->ops && client->ops->drm_exit) { | |
167 | - int err = client->ops->drm_exit(client); | |
173 | + if (client->ops && client->ops->exit) { | |
174 | + err = client->ops->exit(client); | |
168 | 175 | if (err < 0) { |
169 | 176 | dev_err(tegra->dev, |
170 | 177 | "DRM cleanup failed for %s: %d\n", |
... | ... | @@ -177,6 +184,7 @@ |
177 | 184 | |
178 | 185 | mutex_unlock(&tegra->clients_lock); |
179 | 186 | |
187 | + pdev = to_platform_device(tegra->dev); | |
180 | 188 | drm_platform_exit(&tegra_drm_driver, pdev); |
181 | 189 | tegra->drm = NULL; |
182 | 190 | |
183 | 191 | |
184 | 192 | |
185 | 193 | |
... | ... | @@ -409,22 +417,22 @@ |
409 | 417 | struct tegra_drm *tegra = drm->dev_private; |
410 | 418 | struct drm_tegra_open_channel *args = data; |
411 | 419 | struct tegra_drm_context *context; |
412 | - struct host1x_client *client; | |
420 | + struct tegra_drm_client *client; | |
413 | 421 | int err = -ENODEV; |
414 | 422 | |
415 | 423 | context = kzalloc(sizeof(*context), GFP_KERNEL); |
416 | 424 | if (!context) |
417 | 425 | return -ENOMEM; |
418 | 426 | |
419 | - list_for_each_entry(client, &tegra->clients, list) | |
420 | - if (client->class == args->client) { | |
427 | + list_for_each_entry(client, &tegra->clients, base.list) | |
428 | + if (client->base.class == args->client) { | |
421 | 429 | err = client->ops->open_channel(client, context); |
422 | 430 | if (err) |
423 | 431 | break; |
424 | 432 | |
425 | - context->client = client; | |
426 | 433 | list_add(&context->list, &fpriv->contexts); |
427 | 434 | args->context = (uintptr_t)context; |
435 | + context->client = client; | |
428 | 436 | return 0; |
429 | 437 | } |
430 | 438 | |
431 | 439 | |
... | ... | @@ -463,10 +471,10 @@ |
463 | 471 | if (!tegra_drm_file_owns_context(fpriv, context)) |
464 | 472 | return -ENODEV; |
465 | 473 | |
466 | - if (args->index >= context->client->num_syncpts) | |
474 | + if (args->index >= context->client->base.num_syncpts) | |
467 | 475 | return -EINVAL; |
468 | 476 | |
469 | - syncpt = context->client->syncpts[args->index]; | |
477 | + syncpt = context->client->base.syncpts[args->index]; | |
470 | 478 | args->id = host1x_syncpt_id(syncpt); |
471 | 479 | |
472 | 480 | return 0; |
drivers/gpu/host1x/drm/drm.h
... | ... | @@ -44,18 +44,16 @@ |
44 | 44 | struct tegra_fbdev *fbdev; |
45 | 45 | }; |
46 | 46 | |
47 | -struct host1x_client; | |
47 | +struct tegra_drm_client; | |
48 | 48 | |
49 | 49 | struct tegra_drm_context { |
50 | - struct host1x_client *client; | |
50 | + struct tegra_drm_client *client; | |
51 | 51 | struct host1x_channel *channel; |
52 | 52 | struct list_head list; |
53 | 53 | }; |
54 | 54 | |
55 | -struct host1x_client_ops { | |
56 | - int (*drm_init)(struct host1x_client *client, struct drm_device *drm); | |
57 | - int (*drm_exit)(struct host1x_client *client); | |
58 | - int (*open_channel)(struct host1x_client *client, | |
55 | +struct tegra_drm_client_ops { | |
56 | + int (*open_channel)(struct tegra_drm_client *client, | |
59 | 57 | struct tegra_drm_context *context); |
60 | 58 | void (*close_channel)(struct tegra_drm_context *context); |
61 | 59 | int (*submit)(struct tegra_drm_context *context, |
62 | 60 | |
63 | 61 | |
... | ... | @@ -63,21 +61,19 @@ |
63 | 61 | struct drm_file *file); |
64 | 62 | }; |
65 | 63 | |
66 | -struct host1x_client { | |
67 | - struct tegra_drm *tegra; | |
68 | - struct device *dev; | |
64 | +struct tegra_drm_client { | |
65 | + struct host1x_client base; | |
66 | + struct drm_device *drm; | |
69 | 67 | |
70 | - const struct host1x_client_ops *ops; | |
71 | - | |
72 | - enum host1x_class class; | |
73 | - struct host1x_channel *channel; | |
74 | - | |
75 | - struct host1x_syncpt **syncpts; | |
76 | - unsigned int num_syncpts; | |
77 | - | |
78 | - struct list_head list; | |
68 | + const struct tegra_drm_client_ops *ops; | |
79 | 69 | }; |
80 | 70 | |
71 | +static inline struct tegra_drm_client * | |
72 | +to_tegra_drm_client(struct host1x_client *client) | |
73 | +{ | |
74 | + return container_of(client, struct tegra_drm_client, base); | |
75 | +} | |
76 | + | |
81 | 77 | extern int tegra_drm_init(struct tegra_drm *tegra, struct drm_device *drm); |
82 | 78 | extern int tegra_drm_exit(struct tegra_drm *tegra); |
83 | 79 | |
... | ... | @@ -89,7 +85,7 @@ |
89 | 85 | struct tegra_output; |
90 | 86 | |
91 | 87 | struct tegra_dc { |
92 | - struct host1x_client client; | |
88 | + struct tegra_drm_client client; | |
93 | 89 | struct device *dev; |
94 | 90 | spinlock_t lock; |
95 | 91 | |
... | ... | @@ -112,7 +108,8 @@ |
112 | 108 | struct drm_pending_vblank_event *event; |
113 | 109 | }; |
114 | 110 | |
115 | -static inline struct tegra_dc *host1x_client_to_dc(struct host1x_client *client) | |
111 | +static inline struct tegra_dc * | |
112 | +tegra_drm_client_to_dc(struct tegra_drm_client *client) | |
116 | 113 | { |
117 | 114 | return container_of(client, struct tegra_dc, client); |
118 | 115 | } |
drivers/gpu/host1x/drm/gr2d.c
... | ... | @@ -27,20 +27,19 @@ |
27 | 27 | #define GR2D_NUM_REGS 0x4d |
28 | 28 | |
29 | 29 | struct gr2d { |
30 | - struct host1x_client client; | |
30 | + struct tegra_drm_client client; | |
31 | 31 | struct host1x_channel *channel; |
32 | 32 | struct clk *clk; |
33 | 33 | |
34 | 34 | DECLARE_BITMAP(addr_regs, GR2D_NUM_REGS); |
35 | 35 | }; |
36 | 36 | |
37 | -static inline struct gr2d *to_gr2d(struct host1x_client *client) | |
37 | +static inline struct gr2d *to_gr2d(struct tegra_drm_client *client) | |
38 | 38 | { |
39 | 39 | return container_of(client, struct gr2d, client); |
40 | 40 | } |
41 | 41 | |
42 | -static int gr2d_client_init(struct host1x_client *client, | |
43 | - struct drm_device *drm) | |
42 | +static int gr2d_client_init(struct host1x_client *client) | |
44 | 43 | { |
45 | 44 | return 0; |
46 | 45 | } |
... | ... | @@ -50,7 +49,12 @@ |
50 | 49 | return 0; |
51 | 50 | } |
52 | 51 | |
53 | -static int gr2d_open_channel(struct host1x_client *client, | |
52 | +static const struct host1x_client_ops gr2d_client_ops = { | |
53 | + .init = gr2d_client_init, | |
54 | + .exit = gr2d_client_exit, | |
55 | +}; | |
56 | + | |
57 | +static int gr2d_open_channel(struct tegra_drm_client *client, | |
54 | 58 | struct tegra_drm_context *context) |
55 | 59 | { |
56 | 60 | struct gr2d *gr2d = to_gr2d(client); |
... | ... | @@ -140,7 +144,7 @@ |
140 | 144 | job->num_relocs = args->num_relocs; |
141 | 145 | job->num_waitchk = args->num_waitchks; |
142 | 146 | job->client = (u32)args->context; |
143 | - job->class = context->client->class; | |
147 | + job->class = context->client->base.class; | |
144 | 148 | job->serialize = true; |
145 | 149 | |
146 | 150 | while (num_cmdbufs) { |
... | ... | @@ -201,7 +205,7 @@ |
201 | 205 | if (args->timeout && args->timeout < 10000) |
202 | 206 | job->timeout = args->timeout; |
203 | 207 | |
204 | - err = host1x_job_pin(job, context->client->dev); | |
208 | + err = host1x_job_pin(job, context->client->base.dev); | |
205 | 209 | if (err) |
206 | 210 | goto fail; |
207 | 211 | |
... | ... | @@ -221,9 +225,7 @@ |
221 | 225 | return err; |
222 | 226 | } |
223 | 227 | |
224 | -static struct host1x_client_ops gr2d_client_ops = { | |
225 | - .drm_init = gr2d_client_init, | |
226 | - .drm_exit = gr2d_client_exit, | |
228 | +static const struct tegra_drm_client_ops gr2d_ops = { | |
227 | 229 | .open_channel = gr2d_open_channel, |
228 | 230 | .close_channel = gr2d_close_channel, |
229 | 231 | .submit = gr2d_submit, |
230 | 232 | |
... | ... | @@ -279,13 +281,15 @@ |
279 | 281 | return -ENOMEM; |
280 | 282 | } |
281 | 283 | |
282 | - gr2d->client.ops = &gr2d_client_ops; | |
283 | - gr2d->client.dev = dev; | |
284 | - gr2d->client.class = HOST1X_CLASS_GR2D; | |
285 | - gr2d->client.syncpts = syncpts; | |
286 | - gr2d->client.num_syncpts = 1; | |
284 | + INIT_LIST_HEAD(&gr2d->client.base.list); | |
285 | + gr2d->client.base.ops = &gr2d_client_ops; | |
286 | + gr2d->client.base.dev = dev; | |
287 | + gr2d->client.base.class = HOST1X_CLASS_GR2D; | |
288 | + gr2d->client.base.syncpts = syncpts; | |
289 | + gr2d->client.base.num_syncpts = 1; | |
290 | + gr2d->client.ops = &gr2d_ops; | |
287 | 291 | |
288 | - err = host1x_register_client(tegra, &gr2d->client); | |
292 | + err = host1x_register_client(tegra, &gr2d->client.base); | |
289 | 293 | if (err < 0) { |
290 | 294 | dev_err(dev, "failed to register host1x client: %d\n", err); |
291 | 295 | return err; |
292 | 296 | |
... | ... | @@ -307,15 +311,15 @@ |
307 | 311 | unsigned int i; |
308 | 312 | int err; |
309 | 313 | |
310 | - err = host1x_unregister_client(tegra, &gr2d->client); | |
314 | + err = host1x_unregister_client(tegra, &gr2d->client.base); | |
311 | 315 | if (err < 0) { |
312 | 316 | dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", |
313 | 317 | err); |
314 | 318 | return err; |
315 | 319 | } |
316 | 320 | |
317 | - for (i = 0; i < gr2d->client.num_syncpts; i++) | |
318 | - host1x_syncpt_free(gr2d->client.syncpts[i]); | |
321 | + for (i = 0; i < gr2d->client.base.num_syncpts; i++) | |
322 | + host1x_syncpt_free(gr2d->client.base.syncpts[i]); | |
319 | 323 | |
320 | 324 | host1x_channel_free(gr2d->channel); |
321 | 325 | clk_disable_unprepare(gr2d->clk); |
drivers/gpu/host1x/drm/hdmi.c
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | #include "host1x_client.h" |
20 | 20 | |
21 | 21 | struct tegra_hdmi { |
22 | - struct host1x_client client; | |
22 | + struct tegra_drm_client client; | |
23 | 23 | struct tegra_output output; |
24 | 24 | struct device *dev; |
25 | 25 | |
... | ... | @@ -43,7 +43,7 @@ |
43 | 43 | }; |
44 | 44 | |
45 | 45 | static inline struct tegra_hdmi * |
46 | -host1x_client_to_hdmi(struct host1x_client *client) | |
46 | +tegra_drm_client_to_hdmi(struct tegra_drm_client *client) | |
47 | 47 | { |
48 | 48 | return container_of(client, struct tegra_hdmi, client); |
49 | 49 | } |
50 | 50 | |
51 | 51 | |
52 | 52 | |
... | ... | @@ -1116,24 +1116,24 @@ |
1116 | 1116 | return 0; |
1117 | 1117 | } |
1118 | 1118 | |
1119 | -static int tegra_hdmi_drm_init(struct host1x_client *client, | |
1120 | - struct drm_device *drm) | |
1119 | +static int tegra_hdmi_init(struct host1x_client *client) | |
1121 | 1120 | { |
1122 | - struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); | |
1121 | + struct tegra_drm_client *drm = to_tegra_drm_client(client); | |
1122 | + struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm); | |
1123 | 1123 | int err; |
1124 | 1124 | |
1125 | 1125 | hdmi->output.type = TEGRA_OUTPUT_HDMI; |
1126 | 1126 | hdmi->output.dev = client->dev; |
1127 | 1127 | hdmi->output.ops = &hdmi_ops; |
1128 | 1128 | |
1129 | - err = tegra_output_init(drm, &hdmi->output); | |
1129 | + err = tegra_output_init(drm->drm, &hdmi->output); | |
1130 | 1130 | if (err < 0) { |
1131 | 1131 | dev_err(client->dev, "output setup failed: %d\n", err); |
1132 | 1132 | return err; |
1133 | 1133 | } |
1134 | 1134 | |
1135 | 1135 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { |
1136 | - err = tegra_hdmi_debugfs_init(hdmi, drm->primary); | |
1136 | + err = tegra_hdmi_debugfs_init(hdmi, drm->drm->primary); | |
1137 | 1137 | if (err < 0) |
1138 | 1138 | dev_err(client->dev, "debugfs setup failed: %d\n", err); |
1139 | 1139 | } |
1140 | 1140 | |
... | ... | @@ -1141,9 +1141,10 @@ |
1141 | 1141 | return 0; |
1142 | 1142 | } |
1143 | 1143 | |
1144 | -static int tegra_hdmi_drm_exit(struct host1x_client *client) | |
1144 | +static int tegra_hdmi_exit(struct host1x_client *client) | |
1145 | 1145 | { |
1146 | - struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); | |
1146 | + struct tegra_drm_client *drm = to_tegra_drm_client(client); | |
1147 | + struct tegra_hdmi *hdmi = tegra_drm_client_to_hdmi(drm); | |
1147 | 1148 | int err; |
1148 | 1149 | |
1149 | 1150 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { |
... | ... | @@ -1169,8 +1170,8 @@ |
1169 | 1170 | } |
1170 | 1171 | |
1171 | 1172 | static const struct host1x_client_ops hdmi_client_ops = { |
1172 | - .drm_init = tegra_hdmi_drm_init, | |
1173 | - .drm_exit = tegra_hdmi_drm_exit, | |
1173 | + .init = tegra_hdmi_init, | |
1174 | + .exit = tegra_hdmi_exit, | |
1174 | 1175 | }; |
1175 | 1176 | |
1176 | 1177 | static int tegra_hdmi_probe(struct platform_device *pdev) |
1177 | 1178 | |
... | ... | @@ -1246,11 +1247,11 @@ |
1246 | 1247 | |
1247 | 1248 | hdmi->irq = err; |
1248 | 1249 | |
1249 | - hdmi->client.ops = &hdmi_client_ops; | |
1250 | - INIT_LIST_HEAD(&hdmi->client.list); | |
1251 | - hdmi->client.dev = &pdev->dev; | |
1250 | + INIT_LIST_HEAD(&hdmi->client.base.list); | |
1251 | + hdmi->client.base.ops = &hdmi_client_ops; | |
1252 | + hdmi->client.base.dev = &pdev->dev; | |
1252 | 1253 | |
1253 | - err = host1x_register_client(tegra, &hdmi->client); | |
1254 | + err = host1x_register_client(tegra, &hdmi->client.base); | |
1254 | 1255 | if (err < 0) { |
1255 | 1256 | dev_err(&pdev->dev, "failed to register host1x client: %d\n", |
1256 | 1257 | err); |
... | ... | @@ -1268,7 +1269,7 @@ |
1268 | 1269 | struct tegra_hdmi *hdmi = platform_get_drvdata(pdev); |
1269 | 1270 | int err; |
1270 | 1271 | |
1271 | - err = host1x_unregister_client(tegra, &hdmi->client); | |
1272 | + err = host1x_unregister_client(tegra, &hdmi->client.base); | |
1272 | 1273 | if (err < 0) { |
1273 | 1274 | dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", |
1274 | 1275 | err); |
include/linux/host1x.h
... | ... | @@ -25,5 +25,25 @@ |
25 | 25 | HOST1X_CLASS_GR2D_SB = 0x52, |
26 | 26 | }; |
27 | 27 | |
28 | +struct host1x_client; | |
29 | + | |
30 | +struct host1x_client_ops { | |
31 | + int (*init)(struct host1x_client *client); | |
32 | + int (*exit)(struct host1x_client *client); | |
33 | +}; | |
34 | + | |
35 | +struct host1x_client { | |
36 | + struct list_head list; | |
37 | + struct device *dev; | |
38 | + | |
39 | + const struct host1x_client_ops *ops; | |
40 | + | |
41 | + enum host1x_class class; | |
42 | + struct host1x_channel *channel; | |
43 | + | |
44 | + struct host1x_syncpt **syncpts; | |
45 | + unsigned int num_syncpts; | |
46 | +}; | |
47 | + | |
28 | 48 | #endif |