44
44
45
45
static inline struct zynqmp_dpsub * to_zynqmp_dpsub (struct drm_device * drm )
46
46
{
47
- return container_of (drm , struct zynqmp_dpsub , drm ) ;
47
+ return container_of (drm , struct zynqmp_dpsub_drm , dev ) -> dpsub ;
48
48
}
49
49
50
50
/* -----------------------------------------------------------------------------
@@ -146,9 +146,9 @@ static int zynqmp_dpsub_create_planes(struct zynqmp_dpsub *dpsub)
146
146
unsigned int i ;
147
147
int ret ;
148
148
149
- for (i = 0 ; i < ARRAY_SIZE (dpsub -> planes ); i ++ ) {
149
+ for (i = 0 ; i < ARRAY_SIZE (dpsub -> drm -> planes ); i ++ ) {
150
150
struct zynqmp_disp_layer * layer = dpsub -> layers [i ];
151
- struct drm_plane * plane = & dpsub -> planes [i ];
151
+ struct drm_plane * plane = & dpsub -> drm -> planes [i ];
152
152
enum drm_plane_type type ;
153
153
unsigned int num_formats ;
154
154
u32 * formats ;
@@ -160,7 +160,7 @@ static int zynqmp_dpsub_create_planes(struct zynqmp_dpsub *dpsub)
160
160
/* Graphics layer is primary, and video layer is overlay. */
161
161
type = i == ZYNQMP_DPSUB_LAYER_VID
162
162
? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY ;
163
- ret = drm_universal_plane_init (& dpsub -> drm , plane , 0 ,
163
+ ret = drm_universal_plane_init (& dpsub -> drm -> dev , plane , 0 ,
164
164
& zynqmp_dpsub_plane_funcs ,
165
165
formats , num_formats ,
166
166
NULL , type , NULL );
@@ -184,7 +184,7 @@ static int zynqmp_dpsub_create_planes(struct zynqmp_dpsub *dpsub)
184
184
185
185
static inline struct zynqmp_dpsub * crtc_to_dpsub (struct drm_crtc * crtc )
186
186
{
187
- return container_of (crtc , struct zynqmp_dpsub , crtc );
187
+ return container_of (crtc , struct zynqmp_dpsub_drm , crtc )-> dpsub ;
188
188
}
189
189
190
190
static void zynqmp_dpsub_crtc_atomic_enable (struct drm_crtc * crtc ,
@@ -312,11 +312,11 @@ static const struct drm_crtc_funcs zynqmp_dpsub_crtc_funcs = {
312
312
313
313
static int zynqmp_dpsub_create_crtc (struct zynqmp_dpsub * dpsub )
314
314
{
315
- struct drm_plane * plane = & dpsub -> planes [ZYNQMP_DPSUB_LAYER_GFX ];
316
- struct drm_crtc * crtc = & dpsub -> crtc ;
315
+ struct drm_plane * plane = & dpsub -> drm -> planes [ZYNQMP_DPSUB_LAYER_GFX ];
316
+ struct drm_crtc * crtc = & dpsub -> drm -> crtc ;
317
317
int ret ;
318
318
319
- ret = drm_crtc_init_with_planes (& dpsub -> drm , crtc , plane ,
319
+ ret = drm_crtc_init_with_planes (& dpsub -> drm -> dev , crtc , plane ,
320
320
NULL , & zynqmp_dpsub_crtc_funcs , NULL );
321
321
if (ret < 0 )
322
322
return ret ;
@@ -331,11 +331,11 @@ static int zynqmp_dpsub_create_crtc(struct zynqmp_dpsub *dpsub)
331
331
332
332
static void zynqmp_dpsub_map_crtc_to_plane (struct zynqmp_dpsub * dpsub )
333
333
{
334
- u32 possible_crtcs = drm_crtc_mask (& dpsub -> crtc );
334
+ u32 possible_crtcs = drm_crtc_mask (& dpsub -> drm -> crtc );
335
335
unsigned int i ;
336
336
337
- for (i = 0 ; i < ARRAY_SIZE (dpsub -> planes ); i ++ )
338
- dpsub -> planes [i ].possible_crtcs = possible_crtcs ;
337
+ for (i = 0 ; i < ARRAY_SIZE (dpsub -> drm -> planes ); i ++ )
338
+ dpsub -> drm -> planes [i ].possible_crtcs = possible_crtcs ;
339
339
}
340
340
341
341
/**
@@ -347,7 +347,7 @@ static void zynqmp_dpsub_map_crtc_to_plane(struct zynqmp_dpsub *dpsub)
347
347
*/
348
348
void zynqmp_dpsub_handle_vblank (struct zynqmp_dpsub * dpsub )
349
349
{
350
- drm_crtc_handle_vblank (& dpsub -> crtc );
350
+ drm_crtc_handle_vblank (& dpsub -> drm -> crtc );
351
351
}
352
352
353
353
/* -----------------------------------------------------------------------------
@@ -394,7 +394,7 @@ static const struct drm_mode_config_funcs zynqmp_dpsub_mode_config_funcs = {
394
394
395
395
DEFINE_DRM_GEM_DMA_FOPS (zynqmp_dpsub_drm_fops );
396
396
397
- const struct drm_driver zynqmp_dpsub_drm_driver = {
397
+ static const struct drm_driver zynqmp_dpsub_drm_driver = {
398
398
.driver_features = DRIVER_MODESET | DRIVER_GEM |
399
399
DRIVER_ATOMIC ,
400
400
@@ -411,7 +411,7 @@ const struct drm_driver zynqmp_dpsub_drm_driver = {
411
411
412
412
static int zynqmp_dpsub_kms_init (struct zynqmp_dpsub * dpsub )
413
413
{
414
- struct drm_encoder * encoder = & dpsub -> encoder ;
414
+ struct drm_encoder * encoder = & dpsub -> drm -> encoder ;
415
415
struct drm_connector * connector ;
416
416
int ret ;
417
417
@@ -427,8 +427,8 @@ static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub *dpsub)
427
427
zynqmp_dpsub_map_crtc_to_plane (dpsub );
428
428
429
429
/* Create the encoder and attach the bridge. */
430
- encoder -> possible_crtcs |= drm_crtc_mask (& dpsub -> crtc );
431
- drm_simple_encoder_init (& dpsub -> drm , encoder , DRM_MODE_ENCODER_NONE );
430
+ encoder -> possible_crtcs |= drm_crtc_mask (& dpsub -> drm -> crtc );
431
+ drm_simple_encoder_init (& dpsub -> drm -> dev , encoder , DRM_MODE_ENCODER_NONE );
432
432
433
433
ret = drm_bridge_attach (encoder , dpsub -> bridge , NULL ,
434
434
DRM_BRIDGE_ATTACH_NO_CONNECTOR );
@@ -438,7 +438,7 @@ static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub *dpsub)
438
438
}
439
439
440
440
/* Create the connector for the chain of bridges. */
441
- connector = drm_bridge_connector_init (& dpsub -> drm , encoder );
441
+ connector = drm_bridge_connector_init (& dpsub -> drm -> dev , encoder );
442
442
if (IS_ERR (connector )) {
443
443
dev_err (dpsub -> dev , "failed to created connector\n" );
444
444
return PTR_ERR (connector );
@@ -453,11 +453,39 @@ static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub *dpsub)
453
453
return 0 ;
454
454
}
455
455
456
+ static void zynqmp_dpsub_drm_release (struct drm_device * drm , void * res )
457
+ {
458
+ struct zynqmp_dpsub_drm * dpdrm = res ;
459
+
460
+ zynqmp_dpsub_release (dpdrm -> dpsub );
461
+ }
462
+
456
463
int zynqmp_dpsub_drm_init (struct zynqmp_dpsub * dpsub )
457
464
{
458
- struct drm_device * drm = & dpsub -> drm ;
465
+ struct zynqmp_dpsub_drm * dpdrm ;
466
+ struct drm_device * drm ;
459
467
int ret ;
460
468
469
+ /*
470
+ * Allocate the drm_device and immediately add a cleanup action to
471
+ * release the zynqmp_dpsub instance. If any of those operations fail,
472
+ * dpsub->drm will remain NULL, which tells the caller that it must
473
+ * cleanup manually.
474
+ */
475
+ dpdrm = devm_drm_dev_alloc (dpsub -> dev , & zynqmp_dpsub_drm_driver ,
476
+ struct zynqmp_dpsub_drm , dev );
477
+ if (IS_ERR (dpdrm ))
478
+ return PTR_ERR (dpdrm );
479
+
480
+ dpdrm -> dpsub = dpsub ;
481
+ drm = & dpdrm -> dev ;
482
+
483
+ ret = drmm_add_action (drm , zynqmp_dpsub_drm_release , dpdrm );
484
+ if (ret < 0 )
485
+ return ret ;
486
+
487
+ dpsub -> drm = dpdrm ;
488
+
461
489
/* Initialize mode config, vblank and the KMS poll helper. */
462
490
ret = drmm_mode_config_init (drm );
463
491
if (ret < 0 )
@@ -498,7 +526,7 @@ int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
498
526
499
527
void zynqmp_dpsub_drm_cleanup (struct zynqmp_dpsub * dpsub )
500
528
{
501
- struct drm_device * drm = & dpsub -> drm ;
529
+ struct drm_device * drm = & dpsub -> drm -> dev ;
502
530
503
531
drm_dev_unregister (drm );
504
532
drm_atomic_helper_shutdown (drm );
0 commit comments