@@ -93,6 +93,7 @@ struct simplefb_par {
9393
9494static void simplefb_clocks_destroy (struct simplefb_par * par );
9595static void simplefb_regulators_destroy (struct simplefb_par * par );
96+ static void simplefb_detach_genpds (void * res );
9697
9798/*
9899 * fb_ops.fb_destroy is called by the last put_fb_info() call at the end
@@ -105,6 +106,7 @@ static void simplefb_destroy(struct fb_info *info)
105106
106107 simplefb_regulators_destroy (info -> par );
107108 simplefb_clocks_destroy (info -> par );
109+ simplefb_detach_genpds (info -> par );
108110 if (info -> screen_base )
109111 iounmap (info -> screen_base );
110112
@@ -454,13 +456,14 @@ static void simplefb_detach_genpds(void *res)
454456 if (!IS_ERR_OR_NULL (par -> genpds [i ]))
455457 dev_pm_domain_detach (par -> genpds [i ], true);
456458 }
459+ par -> num_genpds = 0 ;
457460}
458461
459462static int simplefb_attach_genpds (struct simplefb_par * par ,
460463 struct platform_device * pdev )
461464{
462465 struct device * dev = & pdev -> dev ;
463- unsigned int i ;
466+ unsigned int i , num_genpds ;
464467 int err ;
465468
466469 err = of_count_phandle_with_args (dev -> of_node , "power-domains" ,
@@ -474,26 +477,35 @@ static int simplefb_attach_genpds(struct simplefb_par *par,
474477 return err ;
475478 }
476479
477- par -> num_genpds = err ;
480+ num_genpds = err ;
478481
479482 /*
480483 * Single power-domain devices are handled by the driver core, so
481484 * nothing to do here.
482485 */
483- if (par -> num_genpds <= 1 )
486+ if (num_genpds <= 1 ) {
487+ par -> num_genpds = num_genpds ;
484488 return 0 ;
489+ }
485490
486- par -> genpds = devm_kcalloc (dev , par -> num_genpds , sizeof (* par -> genpds ),
491+ par -> genpds = devm_kcalloc (dev , num_genpds , sizeof (* par -> genpds ),
487492 GFP_KERNEL );
488493 if (!par -> genpds )
489494 return - ENOMEM ;
490495
491- par -> genpd_links = devm_kcalloc (dev , par -> num_genpds ,
496+ par -> genpd_links = devm_kcalloc (dev , num_genpds ,
492497 sizeof (* par -> genpd_links ),
493498 GFP_KERNEL );
494499 if (!par -> genpd_links )
495500 return - ENOMEM ;
496501
502+ /*
503+ * Set par->num_genpds only after genpds and genpd_links are allocated
504+ * to exit early from simplefb_detach_genpds() without full
505+ * initialisation.
506+ */
507+ par -> num_genpds = num_genpds ;
508+
497509 for (i = 0 ; i < par -> num_genpds ; i ++ ) {
498510 par -> genpds [i ] = dev_pm_domain_attach_by_id (dev , i );
499511 if (IS_ERR (par -> genpds [i ])) {
@@ -515,9 +527,10 @@ static int simplefb_attach_genpds(struct simplefb_par *par,
515527 dev_warn (dev , "failed to link power-domain %u\n" , i );
516528 }
517529
518- return devm_add_action_or_reset ( dev , simplefb_detach_genpds , par ) ;
530+ return 0 ;
519531}
520532#else
533+ static void simplefb_detach_genpds (void * res ) { }
521534static int simplefb_attach_genpds (struct simplefb_par * par ,
522535 struct platform_device * pdev )
523536{
@@ -631,18 +644,20 @@ static int simplefb_probe(struct platform_device *pdev)
631644 ret = devm_aperture_acquire_for_platform_device (pdev , par -> base , par -> size );
632645 if (ret ) {
633646 dev_err (& pdev -> dev , "Unable to acquire aperture: %d\n" , ret );
634- goto error_regulators ;
647+ goto error_genpds ;
635648 }
636649 ret = register_framebuffer (info );
637650 if (ret < 0 ) {
638651 dev_err (& pdev -> dev , "Unable to register simplefb: %d\n" , ret );
639- goto error_regulators ;
652+ goto error_genpds ;
640653 }
641654
642655 dev_info (& pdev -> dev , "fb%d: simplefb registered!\n" , info -> node );
643656
644657 return 0 ;
645658
659+ error_genpds :
660+ simplefb_detach_genpds (par );
646661error_regulators :
647662 simplefb_regulators_destroy (par );
648663error_clocks :
0 commit comments