@@ -1377,7 +1377,9 @@ EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
13771377
13781378#endif /* CONFIG_PM_SLEEP */
13791379
1380- static struct generic_pm_domain_data * genpd_alloc_dev_data (struct device * dev )
1380+ static struct generic_pm_domain_data * genpd_alloc_dev_data (struct device * dev ,
1381+ struct generic_pm_domain * genpd ,
1382+ struct gpd_timing_data * td )
13811383{
13821384 struct generic_pm_domain_data * gpd_data ;
13831385 int ret ;
@@ -1392,8 +1394,32 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
13921394 goto err_put ;
13931395 }
13941396
1397+ if (td )
1398+ gpd_data -> td = * td ;
1399+
1400+ gpd_data -> base .dev = dev ;
1401+ gpd_data -> need_restore = -1 ;
1402+ gpd_data -> td .constraint_changed = true;
1403+ gpd_data -> td .effective_constraint_ns = -1 ;
1404+ gpd_data -> nb .notifier_call = genpd_dev_pm_qos_notifier ;
1405+
1406+ spin_lock_irq (& dev -> power .lock );
1407+
1408+ if (dev -> power .subsys_data -> domain_data ) {
1409+ ret = - EINVAL ;
1410+ goto err_free ;
1411+ }
1412+
1413+ dev -> power .subsys_data -> domain_data = & gpd_data -> base ;
1414+ dev -> pm_domain = & genpd -> domain ;
1415+
1416+ spin_unlock_irq (& dev -> power .lock );
1417+
13951418 return gpd_data ;
13961419
1420+ err_free :
1421+ spin_unlock_irq (& dev -> power .lock );
1422+ kfree (gpd_data );
13971423 err_put :
13981424 dev_pm_put_subsys_data (dev );
13991425 return ERR_PTR (ret );
@@ -1402,6 +1428,13 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev)
14021428static void genpd_free_dev_data (struct device * dev ,
14031429 struct generic_pm_domain_data * gpd_data )
14041430{
1431+ spin_lock_irq (& dev -> power .lock );
1432+
1433+ dev -> pm_domain = NULL ;
1434+ dev -> power .subsys_data -> domain_data = NULL ;
1435+
1436+ spin_unlock_irq (& dev -> power .lock );
1437+
14051438 kfree (gpd_data );
14061439 dev_pm_put_subsys_data (dev );
14071440}
@@ -1423,7 +1456,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
14231456 if (IS_ERR_OR_NULL (genpd ) || IS_ERR_OR_NULL (dev ))
14241457 return - EINVAL ;
14251458
1426- gpd_data = genpd_alloc_dev_data (dev );
1459+ gpd_data = genpd_alloc_dev_data (dev , genpd , td );
14271460 if (IS_ERR (gpd_data ))
14281461 return PTR_ERR (gpd_data );
14291462
@@ -1434,35 +1467,13 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
14341467 goto out ;
14351468 }
14361469
1437- spin_lock_irq (& dev -> power .lock );
1438-
1439- if (dev -> power .subsys_data -> domain_data ) {
1440- spin_unlock_irq (& dev -> power .lock );
1441- ret = - EINVAL ;
1442- goto out ;
1443- }
1444-
1445- dev -> power .subsys_data -> domain_data = & gpd_data -> base ;
1446-
1447- if (td )
1448- gpd_data -> td = * td ;
1449-
1450- dev -> pm_domain = & genpd -> domain ;
1451-
1452- spin_unlock_irq (& dev -> power .lock );
1453-
14541470 if (genpd -> attach_dev )
14551471 genpd -> attach_dev (genpd , dev );
14561472
14571473 genpd -> device_count ++ ;
14581474 genpd -> max_off_time_changed = true;
14591475
1460- gpd_data -> base .dev = dev ;
14611476 list_add_tail (& gpd_data -> base .list_node , & genpd -> dev_list );
1462- gpd_data -> need_restore = -1 ;
1463- gpd_data -> td .constraint_changed = true;
1464- gpd_data -> td .effective_constraint_ns = -1 ;
1465- gpd_data -> nb .notifier_call = genpd_dev_pm_qos_notifier ;
14661477
14671478 out :
14681479 genpd_release_lock (genpd );
@@ -1524,15 +1535,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
15241535 if (genpd -> detach_dev )
15251536 genpd -> detach_dev (genpd , dev );
15261537
1527- spin_lock_irq (& dev -> power .lock );
1528-
1529- dev -> pm_domain = NULL ;
15301538 list_del_init (& pdd -> list_node );
1531- dev -> power .subsys_data -> domain_data = NULL ;
1532-
1533- spin_unlock_irq (& dev -> power .lock );
1534-
1535- pdd -> dev = NULL ;
15361539
15371540 genpd_release_lock (genpd );
15381541
0 commit comments