77#define pr_fmt (fmt ) "PM: " fmt
88
99#include <linux/delay.h>
10+ #include <linux/idr.h>
1011#include <linux/kernel.h>
1112#include <linux/io.h>
1213#include <linux/platform_device.h>
2324#include <linux/cpu.h>
2425#include <linux/debugfs.h>
2526
27+ /* Provides a unique ID for each genpd device */
28+ static DEFINE_IDA (genpd_ida );
29+
2630#define GENPD_RETRY_MAX_MS 250 /* Approximate */
2731
2832#define GENPD_DEV_CALLBACK (genpd , type , callback , dev ) \
@@ -171,6 +175,7 @@ static const struct genpd_lock_ops genpd_raw_spin_ops = {
171175#define genpd_is_cpu_domain (genpd ) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
172176#define genpd_is_rpm_always_on (genpd ) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
173177#define genpd_is_opp_table_fw (genpd ) (genpd->flags & GENPD_FLAG_OPP_TABLE_FW)
178+ #define genpd_is_dev_name_fw (genpd ) (genpd->flags & GENPD_FLAG_DEV_NAME_FW)
174179
175180static inline bool irq_safe_dev_in_sleep_domain (struct device * dev ,
176181 const struct generic_pm_domain * genpd )
@@ -189,7 +194,7 @@ static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
189194
190195 if (ret )
191196 dev_warn_once (dev , "PM domain %s will not be powered off\n" ,
192- genpd -> name );
197+ dev_name ( & genpd -> dev ) );
193198
194199 return ret ;
195200}
@@ -274,7 +279,7 @@ static void genpd_debug_remove(struct generic_pm_domain *genpd)
274279 if (!genpd_debugfs_dir )
275280 return ;
276281
277- debugfs_lookup_and_remove (genpd -> name , genpd_debugfs_dir );
282+ debugfs_lookup_and_remove (dev_name ( & genpd -> dev ) , genpd_debugfs_dir );
278283}
279284
280285static void genpd_update_accounting (struct generic_pm_domain * genpd )
@@ -731,7 +736,7 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
731736 genpd -> states [state_idx ].power_on_latency_ns = elapsed_ns ;
732737 genpd -> gd -> max_off_time_changed = true;
733738 pr_debug ("%s: Power-%s latency exceeded, new value %lld ns\n" ,
734- genpd -> name , "on" , elapsed_ns );
739+ dev_name ( & genpd -> dev ) , "on" , elapsed_ns );
735740
736741out :
737742 raw_notifier_call_chain (& genpd -> power_notifiers , GENPD_NOTIFY_ON , NULL );
@@ -782,7 +787,7 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed)
782787 genpd -> states [state_idx ].power_off_latency_ns = elapsed_ns ;
783788 genpd -> gd -> max_off_time_changed = true;
784789 pr_debug ("%s: Power-%s latency exceeded, new value %lld ns\n" ,
785- genpd -> name , "off" , elapsed_ns );
790+ dev_name ( & genpd -> dev ) , "off" , elapsed_ns );
786791
787792out :
788793 raw_notifier_call_chain (& genpd -> power_notifiers , GENPD_NOTIFY_OFF ,
@@ -1941,7 +1946,7 @@ int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb)
19411946
19421947 if (ret ) {
19431948 dev_warn (dev , "failed to add notifier for PM domain %s\n" ,
1944- genpd -> name );
1949+ dev_name ( & genpd -> dev ) );
19451950 return ret ;
19461951 }
19471952
@@ -1988,7 +1993,7 @@ int dev_pm_genpd_remove_notifier(struct device *dev)
19881993
19891994 if (ret ) {
19901995 dev_warn (dev , "failed to remove notifier for PM domain %s\n" ,
1991- genpd -> name );
1996+ dev_name ( & genpd -> dev ) );
19921997 return ret ;
19931998 }
19941999
@@ -2014,7 +2019,7 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
20142019 */
20152020 if (!genpd_is_irq_safe (genpd ) && genpd_is_irq_safe (subdomain )) {
20162021 WARN (1 , "Parent %s of subdomain %s must be IRQ safe\n" ,
2017- genpd -> name , subdomain -> name );
2022+ dev_name ( & genpd -> dev ) , subdomain -> name );
20182023 return - EINVAL ;
20192024 }
20202025
@@ -2089,7 +2094,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
20892094
20902095 if (!list_empty (& subdomain -> parent_links ) || subdomain -> device_count ) {
20912096 pr_warn ("%s: unable to remove subdomain %s\n" ,
2092- genpd -> name , subdomain -> name );
2097+ dev_name ( & genpd -> dev ) , subdomain -> name );
20932098 ret = - EBUSY ;
20942099 goto out ;
20952100 }
@@ -2226,6 +2231,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
22262231 genpd -> status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON ;
22272232 genpd -> device_count = 0 ;
22282233 genpd -> provider = NULL ;
2234+ genpd -> device_id = - ENXIO ;
22292235 genpd -> has_provider = false;
22302236 genpd -> accounting_time = ktime_get_mono_fast_ns ();
22312237 genpd -> domain .ops .runtime_suspend = genpd_runtime_suspend ;
@@ -2266,7 +2272,18 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
22662272 return ret ;
22672273
22682274 device_initialize (& genpd -> dev );
2269- dev_set_name (& genpd -> dev , "%s" , genpd -> name );
2275+
2276+ if (!genpd_is_dev_name_fw (genpd )) {
2277+ dev_set_name (& genpd -> dev , "%s" , genpd -> name );
2278+ } else {
2279+ ret = ida_alloc (& genpd_ida , GFP_KERNEL );
2280+ if (ret < 0 ) {
2281+ put_device (& genpd -> dev );
2282+ return ret ;
2283+ }
2284+ genpd -> device_id = ret ;
2285+ dev_set_name (& genpd -> dev , "%s_%u" , genpd -> name , genpd -> device_id );
2286+ }
22702287
22712288 mutex_lock (& gpd_list_lock );
22722289 list_add (& genpd -> gpd_list_node , & gpd_list );
@@ -2288,13 +2305,13 @@ static int genpd_remove(struct generic_pm_domain *genpd)
22882305
22892306 if (genpd -> has_provider ) {
22902307 genpd_unlock (genpd );
2291- pr_err ("Provider present, unable to remove %s\n" , genpd -> name );
2308+ pr_err ("Provider present, unable to remove %s\n" , dev_name ( & genpd -> dev ) );
22922309 return - EBUSY ;
22932310 }
22942311
22952312 if (!list_empty (& genpd -> parent_links ) || genpd -> device_count ) {
22962313 genpd_unlock (genpd );
2297- pr_err ("%s: unable to remove %s\n" , __func__ , genpd -> name );
2314+ pr_err ("%s: unable to remove %s\n" , __func__ , dev_name ( & genpd -> dev ) );
22982315 return - EBUSY ;
22992316 }
23002317
@@ -2308,9 +2325,11 @@ static int genpd_remove(struct generic_pm_domain *genpd)
23082325 genpd_unlock (genpd );
23092326 genpd_debug_remove (genpd );
23102327 cancel_work_sync (& genpd -> power_off_work );
2328+ if (genpd -> device_id != - ENXIO )
2329+ ida_free (& genpd_ida , genpd -> device_id );
23112330 genpd_free_data (genpd );
23122331
2313- pr_debug ("%s: removed %s\n" , __func__ , genpd -> name );
2332+ pr_debug ("%s: removed %s\n" , __func__ , dev_name ( & genpd -> dev ) );
23142333
23152334 return 0 ;
23162335}
@@ -3320,12 +3339,12 @@ static int genpd_summary_one(struct seq_file *s,
33203339 else
33213340 snprintf (state , sizeof (state ), "%s" ,
33223341 status_lookup [genpd -> status ]);
3323- seq_printf (s , "%-30s %-30s %u" , genpd -> name , state , genpd -> performance_state );
3342+ seq_printf (s , "%-30s %-30s %u" , dev_name ( & genpd -> dev ) , state , genpd -> performance_state );
33243343
33253344 /*
33263345 * Modifications on the list require holding locks on both
33273346 * parent and child, so we are safe.
3328- * Also genpd-> name is immutable.
3347+ * Also the device name is immutable.
33293348 */
33303349 list_for_each_entry (link , & genpd -> parent_links , parent_node ) {
33313350 if (list_is_first (& link -> parent_node , & genpd -> parent_links ))
@@ -3550,7 +3569,7 @@ static void genpd_debug_add(struct generic_pm_domain *genpd)
35503569 if (!genpd_debugfs_dir )
35513570 return ;
35523571
3553- d = debugfs_create_dir (genpd -> name , genpd_debugfs_dir );
3572+ d = debugfs_create_dir (dev_name ( & genpd -> dev ) , genpd_debugfs_dir );
35543573
35553574 debugfs_create_file ("current_state" , 0444 ,
35563575 d , genpd , & status_fops );
0 commit comments