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 ,
@@ -1940,7 +1945,7 @@ int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb)
19401945
19411946 if (ret ) {
19421947 dev_warn (dev , "failed to add notifier for PM domain %s\n" ,
1943- genpd -> name );
1948+ dev_name ( & genpd -> dev ) );
19441949 return ret ;
19451950 }
19461951
@@ -1987,7 +1992,7 @@ int dev_pm_genpd_remove_notifier(struct device *dev)
19871992
19881993 if (ret ) {
19891994 dev_warn (dev , "failed to remove notifier for PM domain %s\n" ,
1990- genpd -> name );
1995+ dev_name ( & genpd -> dev ) );
19911996 return ret ;
19921997 }
19931998
@@ -2013,7 +2018,7 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
20132018 */
20142019 if (!genpd_is_irq_safe (genpd ) && genpd_is_irq_safe (subdomain )) {
20152020 WARN (1 , "Parent %s of subdomain %s must be IRQ safe\n" ,
2016- genpd -> name , subdomain -> name );
2021+ dev_name ( & genpd -> dev ) , subdomain -> name );
20172022 return - EINVAL ;
20182023 }
20192024
@@ -2088,7 +2093,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
20882093
20892094 if (!list_empty (& subdomain -> parent_links ) || subdomain -> device_count ) {
20902095 pr_warn ("%s: unable to remove subdomain %s\n" ,
2091- genpd -> name , subdomain -> name );
2096+ dev_name ( & genpd -> dev ) , subdomain -> name );
20922097 ret = - EBUSY ;
20932098 goto out ;
20942099 }
@@ -2225,6 +2230,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
22252230 genpd -> status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON ;
22262231 genpd -> device_count = 0 ;
22272232 genpd -> provider = NULL ;
2233+ genpd -> device_id = - ENXIO ;
22282234 genpd -> has_provider = false;
22292235 genpd -> accounting_time = ktime_get_mono_fast_ns ();
22302236 genpd -> domain .ops .runtime_suspend = genpd_runtime_suspend ;
@@ -2265,7 +2271,18 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
22652271 return ret ;
22662272
22672273 device_initialize (& genpd -> dev );
2268- dev_set_name (& genpd -> dev , "%s" , genpd -> name );
2274+
2275+ if (!genpd_is_dev_name_fw (genpd )) {
2276+ dev_set_name (& genpd -> dev , "%s" , genpd -> name );
2277+ } else {
2278+ ret = ida_alloc (& genpd_ida , GFP_KERNEL );
2279+ if (ret < 0 ) {
2280+ put_device (& genpd -> dev );
2281+ return ret ;
2282+ }
2283+ genpd -> device_id = ret ;
2284+ dev_set_name (& genpd -> dev , "%s_%u" , genpd -> name , genpd -> device_id );
2285+ }
22692286
22702287 mutex_lock (& gpd_list_lock );
22712288 list_add (& genpd -> gpd_list_node , & gpd_list );
@@ -2287,13 +2304,13 @@ static int genpd_remove(struct generic_pm_domain *genpd)
22872304
22882305 if (genpd -> has_provider ) {
22892306 genpd_unlock (genpd );
2290- pr_err ("Provider present, unable to remove %s\n" , genpd -> name );
2307+ pr_err ("Provider present, unable to remove %s\n" , dev_name ( & genpd -> dev ) );
22912308 return - EBUSY ;
22922309 }
22932310
22942311 if (!list_empty (& genpd -> parent_links ) || genpd -> device_count ) {
22952312 genpd_unlock (genpd );
2296- pr_err ("%s: unable to remove %s\n" , __func__ , genpd -> name );
2313+ pr_err ("%s: unable to remove %s\n" , __func__ , dev_name ( & genpd -> dev ) );
22972314 return - EBUSY ;
22982315 }
22992316
@@ -2307,9 +2324,11 @@ static int genpd_remove(struct generic_pm_domain *genpd)
23072324 genpd_unlock (genpd );
23082325 genpd_debug_remove (genpd );
23092326 cancel_work_sync (& genpd -> power_off_work );
2327+ if (genpd -> device_id != - ENXIO )
2328+ ida_free (& genpd_ida , genpd -> device_id );
23102329 genpd_free_data (genpd );
23112330
2312- pr_debug ("%s: removed %s\n" , __func__ , genpd -> name );
2331+ pr_debug ("%s: removed %s\n" , __func__ , dev_name ( & genpd -> dev ) );
23132332
23142333 return 0 ;
23152334}
@@ -3272,12 +3291,12 @@ static int genpd_summary_one(struct seq_file *s,
32723291 else
32733292 snprintf (state , sizeof (state ), "%s" ,
32743293 status_lookup [genpd -> status ]);
3275- seq_printf (s , "%-30s %-30s %u" , genpd -> name , state , genpd -> performance_state );
3294+ seq_printf (s , "%-30s %-30s %u" , dev_name ( & genpd -> dev ) , state , genpd -> performance_state );
32763295
32773296 /*
32783297 * Modifications on the list require holding locks on both
32793298 * parent and child, so we are safe.
3280- * Also genpd-> name is immutable.
3299+ * Also the device name is immutable.
32813300 */
32823301 list_for_each_entry (link , & genpd -> parent_links , parent_node ) {
32833302 if (list_is_first (& link -> parent_node , & genpd -> parent_links ))
@@ -3502,7 +3521,7 @@ static void genpd_debug_add(struct generic_pm_domain *genpd)
35023521 if (!genpd_debugfs_dir )
35033522 return ;
35043523
3505- d = debugfs_create_dir (genpd -> name , genpd_debugfs_dir );
3524+ d = debugfs_create_dir (dev_name ( & genpd -> dev ) , genpd_debugfs_dir );
35063525
35073526 debugfs_create_file ("current_state" , 0444 ,
35083527 d , genpd , & status_fops );
0 commit comments