@@ -235,6 +235,186 @@ void device_pm_move_to_tail(struct device *dev)
235
235
device_links_read_unlock (idx );
236
236
}
237
237
238
+ #define to_devlink (dev ) container_of((dev), struct device_link, link_dev)
239
+
240
+ static ssize_t status_show (struct device * dev ,
241
+ struct device_attribute * attr , char * buf )
242
+ {
243
+ char * status ;
244
+
245
+ switch (to_devlink (dev )-> status ) {
246
+ case DL_STATE_NONE :
247
+ status = "not tracked" ; break ;
248
+ case DL_STATE_DORMANT :
249
+ status = "dormant" ; break ;
250
+ case DL_STATE_AVAILABLE :
251
+ status = "available" ; break ;
252
+ case DL_STATE_CONSUMER_PROBE :
253
+ status = "consumer probing" ; break ;
254
+ case DL_STATE_ACTIVE :
255
+ status = "active" ; break ;
256
+ case DL_STATE_SUPPLIER_UNBIND :
257
+ status = "supplier unbinding" ; break ;
258
+ default :
259
+ status = "unknown" ; break ;
260
+ }
261
+ return sprintf (buf , "%s\n" , status );
262
+ }
263
+ static DEVICE_ATTR_RO (status );
264
+
265
+ static ssize_t auto_remove_on_show (struct device * dev ,
266
+ struct device_attribute * attr , char * buf )
267
+ {
268
+ struct device_link * link = to_devlink (dev );
269
+ char * str ;
270
+
271
+ if (link -> flags & DL_FLAG_AUTOREMOVE_SUPPLIER )
272
+ str = "supplier unbind" ;
273
+ else if (link -> flags & DL_FLAG_AUTOREMOVE_CONSUMER )
274
+ str = "consumer unbind" ;
275
+ else
276
+ str = "never" ;
277
+
278
+ return sprintf (buf , "%s\n" , str );
279
+ }
280
+ static DEVICE_ATTR_RO (auto_remove_on );
281
+
282
+ static ssize_t runtime_pm_show (struct device * dev ,
283
+ struct device_attribute * attr , char * buf )
284
+ {
285
+ struct device_link * link = to_devlink (dev );
286
+
287
+ return sprintf (buf , "%d\n" , !!(link -> flags & DL_FLAG_PM_RUNTIME ));
288
+ }
289
+ static DEVICE_ATTR_RO (runtime_pm );
290
+
291
+ static ssize_t sync_state_only_show (struct device * dev ,
292
+ struct device_attribute * attr , char * buf )
293
+ {
294
+ struct device_link * link = to_devlink (dev );
295
+
296
+ return sprintf (buf , "%d\n" , !!(link -> flags & DL_FLAG_SYNC_STATE_ONLY ));
297
+ }
298
+ static DEVICE_ATTR_RO (sync_state_only );
299
+
300
+ static struct attribute * devlink_attrs [] = {
301
+ & dev_attr_status .attr ,
302
+ & dev_attr_auto_remove_on .attr ,
303
+ & dev_attr_runtime_pm .attr ,
304
+ & dev_attr_sync_state_only .attr ,
305
+ NULL ,
306
+ };
307
+ ATTRIBUTE_GROUPS (devlink );
308
+
309
+ static void devlink_dev_release (struct device * dev )
310
+ {
311
+ kfree (to_devlink (dev ));
312
+ }
313
+
314
+ static struct class devlink_class = {
315
+ .name = "devlink" ,
316
+ .owner = THIS_MODULE ,
317
+ .dev_groups = devlink_groups ,
318
+ .dev_release = devlink_dev_release ,
319
+ };
320
+
321
+ static int devlink_add_symlinks (struct device * dev ,
322
+ struct class_interface * class_intf )
323
+ {
324
+ int ret ;
325
+ size_t len ;
326
+ struct device_link * link = to_devlink (dev );
327
+ struct device * sup = link -> supplier ;
328
+ struct device * con = link -> consumer ;
329
+ char * buf ;
330
+
331
+ len = max (strlen (dev_name (sup )), strlen (dev_name (con )));
332
+ len += strlen ("supplier:" ) + 1 ;
333
+ buf = kzalloc (len , GFP_KERNEL );
334
+ if (!buf )
335
+ return - ENOMEM ;
336
+
337
+ ret = sysfs_create_link (& link -> link_dev .kobj , & sup -> kobj , "supplier" );
338
+ if (ret )
339
+ goto out ;
340
+
341
+ ret = sysfs_create_link (& link -> link_dev .kobj , & con -> kobj , "consumer" );
342
+ if (ret )
343
+ goto err_con ;
344
+
345
+ snprintf (buf , len , "consumer:%s" , dev_name (con ));
346
+ ret = sysfs_create_link (& sup -> kobj , & link -> link_dev .kobj , buf );
347
+ if (ret )
348
+ goto err_con_dev ;
349
+
350
+ snprintf (buf , len , "supplier:%s" , dev_name (sup ));
351
+ ret = sysfs_create_link (& con -> kobj , & link -> link_dev .kobj , buf );
352
+ if (ret )
353
+ goto err_sup_dev ;
354
+
355
+ goto out ;
356
+
357
+ err_sup_dev :
358
+ snprintf (buf , len , "consumer:%s" , dev_name (con ));
359
+ sysfs_remove_link (& sup -> kobj , buf );
360
+ err_con_dev :
361
+ sysfs_remove_link (& link -> link_dev .kobj , "consumer" );
362
+ err_con :
363
+ sysfs_remove_link (& link -> link_dev .kobj , "supplier" );
364
+ out :
365
+ kfree (buf );
366
+ return ret ;
367
+ }
368
+
369
+ static void devlink_remove_symlinks (struct device * dev ,
370
+ struct class_interface * class_intf )
371
+ {
372
+ struct device_link * link = to_devlink (dev );
373
+ size_t len ;
374
+ struct device * sup = link -> supplier ;
375
+ struct device * con = link -> consumer ;
376
+ char * buf ;
377
+
378
+ sysfs_remove_link (& link -> link_dev .kobj , "consumer" );
379
+ sysfs_remove_link (& link -> link_dev .kobj , "supplier" );
380
+
381
+ len = max (strlen (dev_name (sup )), strlen (dev_name (con )));
382
+ len += strlen ("supplier:" ) + 1 ;
383
+ buf = kzalloc (len , GFP_KERNEL );
384
+ if (!buf ) {
385
+ WARN (1 , "Unable to properly free device link symlinks!\n" );
386
+ return ;
387
+ }
388
+
389
+ snprintf (buf , len , "supplier:%s" , dev_name (sup ));
390
+ sysfs_remove_link (& con -> kobj , buf );
391
+ snprintf (buf , len , "consumer:%s" , dev_name (con ));
392
+ sysfs_remove_link (& sup -> kobj , buf );
393
+ kfree (buf );
394
+ }
395
+
396
+ static struct class_interface devlink_class_intf = {
397
+ .class = & devlink_class ,
398
+ .add_dev = devlink_add_symlinks ,
399
+ .remove_dev = devlink_remove_symlinks ,
400
+ };
401
+
402
+ static int __init devlink_class_init (void )
403
+ {
404
+ int ret ;
405
+
406
+ ret = class_register (& devlink_class );
407
+ if (ret )
408
+ return ret ;
409
+
410
+ ret = class_interface_register (& devlink_class_intf );
411
+ if (ret )
412
+ class_unregister (& devlink_class );
413
+
414
+ return ret ;
415
+ }
416
+ postcore_initcall (devlink_class_init );
417
+
238
418
#define DL_MANAGED_LINK_FLAGS (DL_FLAG_AUTOREMOVE_CONSUMER | \
239
419
DL_FLAG_AUTOREMOVE_SUPPLIER | \
240
420
DL_FLAG_AUTOPROBE_CONSUMER | \
@@ -407,13 +587,6 @@ struct device_link *device_link_add(struct device *consumer,
407
587
408
588
refcount_set (& link -> rpm_active , 1 );
409
589
410
- if (flags & DL_FLAG_PM_RUNTIME ) {
411
- if (flags & DL_FLAG_RPM_ACTIVE )
412
- refcount_inc (& link -> rpm_active );
413
-
414
- pm_runtime_new_link (consumer );
415
- }
416
-
417
590
get_device (supplier );
418
591
link -> supplier = supplier ;
419
592
INIT_LIST_HEAD (& link -> s_node );
@@ -423,6 +596,25 @@ struct device_link *device_link_add(struct device *consumer,
423
596
link -> flags = flags ;
424
597
kref_init (& link -> kref );
425
598
599
+ link -> link_dev .class = & devlink_class ;
600
+ device_set_pm_not_required (& link -> link_dev );
601
+ dev_set_name (& link -> link_dev , "%s:%s" ,
602
+ dev_name (supplier ), dev_name (consumer ));
603
+ if (device_register (& link -> link_dev )) {
604
+ put_device (consumer );
605
+ put_device (supplier );
606
+ kfree (link );
607
+ link = NULL ;
608
+ goto out ;
609
+ }
610
+
611
+ if (flags & DL_FLAG_PM_RUNTIME ) {
612
+ if (flags & DL_FLAG_RPM_ACTIVE )
613
+ refcount_inc (& link -> rpm_active );
614
+
615
+ pm_runtime_new_link (consumer );
616
+ }
617
+
426
618
/* Determine the initial link state. */
427
619
if (flags & DL_FLAG_STATELESS )
428
620
link -> status = DL_STATE_NONE ;
@@ -545,7 +737,7 @@ static void device_link_free(struct device_link *link)
545
737
546
738
put_device (link -> consumer );
547
739
put_device (link -> supplier );
548
- kfree ( link );
740
+ device_unregister ( & link -> link_dev );
549
741
}
550
742
551
743
#ifdef CONFIG_SRCU
@@ -1159,6 +1351,9 @@ static void device_links_purge(struct device *dev)
1159
1351
{
1160
1352
struct device_link * link , * ln ;
1161
1353
1354
+ if (dev -> class == & devlink_class )
1355
+ return ;
1356
+
1162
1357
mutex_lock (& wfs_lock );
1163
1358
list_del (& dev -> links .needs_suppliers );
1164
1359
mutex_unlock (& wfs_lock );
0 commit comments