7
7
#define pr_fmt (fmt ) "PM: " fmt
8
8
9
9
#include <linux/delay.h>
10
+ #include <linux/idr.h>
10
11
#include <linux/kernel.h>
11
12
#include <linux/io.h>
12
13
#include <linux/platform_device.h>
23
24
#include <linux/cpu.h>
24
25
#include <linux/debugfs.h>
25
26
27
+ /* Provides a unique ID for each genpd device */
28
+ static DEFINE_IDA (genpd_ida );
29
+
26
30
#define GENPD_RETRY_MAX_MS 250 /* Approximate */
27
31
28
32
#define GENPD_DEV_CALLBACK (genpd , type , callback , dev ) \
@@ -171,6 +175,7 @@ static const struct genpd_lock_ops genpd_raw_spin_ops = {
171
175
#define genpd_is_cpu_domain (genpd ) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
172
176
#define genpd_is_rpm_always_on (genpd ) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
173
177
#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)
174
179
175
180
static inline bool irq_safe_dev_in_sleep_domain (struct device * dev ,
176
181
const struct generic_pm_domain * genpd )
@@ -189,7 +194,7 @@ static inline bool irq_safe_dev_in_sleep_domain(struct device *dev,
189
194
190
195
if (ret )
191
196
dev_warn_once (dev , "PM domain %s will not be powered off\n" ,
192
- genpd -> name );
197
+ dev_name ( & genpd -> dev ) );
193
198
194
199
return ret ;
195
200
}
@@ -274,7 +279,7 @@ static void genpd_debug_remove(struct generic_pm_domain *genpd)
274
279
if (!genpd_debugfs_dir )
275
280
return ;
276
281
277
- debugfs_lookup_and_remove (genpd -> name , genpd_debugfs_dir );
282
+ debugfs_lookup_and_remove (dev_name ( & genpd -> dev ) , genpd_debugfs_dir );
278
283
}
279
284
280
285
static 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)
731
736
genpd -> states [state_idx ].power_on_latency_ns = elapsed_ns ;
732
737
genpd -> gd -> max_off_time_changed = true;
733
738
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 );
735
740
736
741
out :
737
742
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)
782
787
genpd -> states [state_idx ].power_off_latency_ns = elapsed_ns ;
783
788
genpd -> gd -> max_off_time_changed = true;
784
789
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 );
786
791
787
792
out :
788
793
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)
1940
1945
1941
1946
if (ret ) {
1942
1947
dev_warn (dev , "failed to add notifier for PM domain %s\n" ,
1943
- genpd -> name );
1948
+ dev_name ( & genpd -> dev ) );
1944
1949
return ret ;
1945
1950
}
1946
1951
@@ -1987,7 +1992,7 @@ int dev_pm_genpd_remove_notifier(struct device *dev)
1987
1992
1988
1993
if (ret ) {
1989
1994
dev_warn (dev , "failed to remove notifier for PM domain %s\n" ,
1990
- genpd -> name );
1995
+ dev_name ( & genpd -> dev ) );
1991
1996
return ret ;
1992
1997
}
1993
1998
@@ -2013,7 +2018,7 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
2013
2018
*/
2014
2019
if (!genpd_is_irq_safe (genpd ) && genpd_is_irq_safe (subdomain )) {
2015
2020
WARN (1 , "Parent %s of subdomain %s must be IRQ safe\n" ,
2016
- genpd -> name , subdomain -> name );
2021
+ dev_name ( & genpd -> dev ) , subdomain -> name );
2017
2022
return - EINVAL ;
2018
2023
}
2019
2024
@@ -2088,7 +2093,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
2088
2093
2089
2094
if (!list_empty (& subdomain -> parent_links ) || subdomain -> device_count ) {
2090
2095
pr_warn ("%s: unable to remove subdomain %s\n" ,
2091
- genpd -> name , subdomain -> name );
2096
+ dev_name ( & genpd -> dev ) , subdomain -> name );
2092
2097
ret = - EBUSY ;
2093
2098
goto out ;
2094
2099
}
@@ -2225,6 +2230,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
2225
2230
genpd -> status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON ;
2226
2231
genpd -> device_count = 0 ;
2227
2232
genpd -> provider = NULL ;
2233
+ genpd -> device_id = - ENXIO ;
2228
2234
genpd -> has_provider = false;
2229
2235
genpd -> accounting_time = ktime_get_mono_fast_ns ();
2230
2236
genpd -> domain .ops .runtime_suspend = genpd_runtime_suspend ;
@@ -2265,7 +2271,18 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
2265
2271
return ret ;
2266
2272
2267
2273
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
+ }
2269
2286
2270
2287
mutex_lock (& gpd_list_lock );
2271
2288
list_add (& genpd -> gpd_list_node , & gpd_list );
@@ -2287,13 +2304,13 @@ static int genpd_remove(struct generic_pm_domain *genpd)
2287
2304
2288
2305
if (genpd -> has_provider ) {
2289
2306
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 ) );
2291
2308
return - EBUSY ;
2292
2309
}
2293
2310
2294
2311
if (!list_empty (& genpd -> parent_links ) || genpd -> device_count ) {
2295
2312
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 ) );
2297
2314
return - EBUSY ;
2298
2315
}
2299
2316
@@ -2307,9 +2324,11 @@ static int genpd_remove(struct generic_pm_domain *genpd)
2307
2324
genpd_unlock (genpd );
2308
2325
genpd_debug_remove (genpd );
2309
2326
cancel_work_sync (& genpd -> power_off_work );
2327
+ if (genpd -> device_id != - ENXIO )
2328
+ ida_free (& genpd_ida , genpd -> device_id );
2310
2329
genpd_free_data (genpd );
2311
2330
2312
- pr_debug ("%s: removed %s\n" , __func__ , genpd -> name );
2331
+ pr_debug ("%s: removed %s\n" , __func__ , dev_name ( & genpd -> dev ) );
2313
2332
2314
2333
return 0 ;
2315
2334
}
@@ -3272,12 +3291,12 @@ static int genpd_summary_one(struct seq_file *s,
3272
3291
else
3273
3292
snprintf (state , sizeof (state ), "%s" ,
3274
3293
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 );
3276
3295
3277
3296
/*
3278
3297
* Modifications on the list require holding locks on both
3279
3298
* parent and child, so we are safe.
3280
- * Also genpd-> name is immutable.
3299
+ * Also the device name is immutable.
3281
3300
*/
3282
3301
list_for_each_entry (link , & genpd -> parent_links , parent_node ) {
3283
3302
if (list_is_first (& link -> parent_node , & genpd -> parent_links ))
@@ -3502,7 +3521,7 @@ static void genpd_debug_add(struct generic_pm_domain *genpd)
3502
3521
if (!genpd_debugfs_dir )
3503
3522
return ;
3504
3523
3505
- d = debugfs_create_dir (genpd -> name , genpd_debugfs_dir );
3524
+ d = debugfs_create_dir (dev_name ( & genpd -> dev ) , genpd_debugfs_dir );
3506
3525
3507
3526
debugfs_create_file ("current_state" , 0444 ,
3508
3527
d , genpd , & status_fops );
0 commit comments