4
4
#include <linux/virtio_config.h>
5
5
#include <linux/module.h>
6
6
#include <linux/idr.h>
7
+ #include <linux/of.h>
7
8
#include <uapi/linux/virtio_ids.h>
8
9
9
10
/* Unique numbering for virtio devices. */
@@ -292,6 +293,9 @@ static int virtio_dev_remove(struct device *_d)
292
293
293
294
/* Acknowledge the device's existence again. */
294
295
virtio_add_status (dev , VIRTIO_CONFIG_S_ACKNOWLEDGE );
296
+
297
+ of_node_put (dev -> dev .of_node );
298
+
295
299
return 0 ;
296
300
}
297
301
@@ -319,6 +323,43 @@ void unregister_virtio_driver(struct virtio_driver *driver)
319
323
}
320
324
EXPORT_SYMBOL_GPL (unregister_virtio_driver );
321
325
326
+ static int virtio_device_of_init (struct virtio_device * dev )
327
+ {
328
+ struct device_node * np , * pnode = dev_of_node (dev -> dev .parent );
329
+ char compat [] = "virtio,deviceXXXXXXXX" ;
330
+ int ret , count ;
331
+
332
+ if (!pnode )
333
+ return 0 ;
334
+
335
+ count = of_get_available_child_count (pnode );
336
+ if (!count )
337
+ return 0 ;
338
+
339
+ /* There can be only 1 child node */
340
+ if (WARN_ON (count > 1 ))
341
+ return - EINVAL ;
342
+
343
+ np = of_get_next_available_child (pnode , NULL );
344
+ if (WARN_ON (!np ))
345
+ return - ENODEV ;
346
+
347
+ ret = snprintf (compat , sizeof (compat ), "virtio,device%x" , dev -> id .device );
348
+ BUG_ON (ret >= sizeof (compat ));
349
+
350
+ if (!of_device_is_compatible (np , compat )) {
351
+ ret = - EINVAL ;
352
+ goto out ;
353
+ }
354
+
355
+ dev -> dev .of_node = np ;
356
+ return 0 ;
357
+
358
+ out :
359
+ of_node_put (np );
360
+ return ret ;
361
+ }
362
+
322
363
/**
323
364
* register_virtio_device - register virtio device
324
365
* @dev : virtio device to be registered
@@ -343,6 +384,10 @@ int register_virtio_device(struct virtio_device *dev)
343
384
dev -> index = err ;
344
385
dev_set_name (& dev -> dev , "virtio%u" , dev -> index );
345
386
387
+ err = virtio_device_of_init (dev );
388
+ if (err )
389
+ goto out_ida_remove ;
390
+
346
391
spin_lock_init (& dev -> config_lock );
347
392
dev -> config_enabled = false;
348
393
dev -> config_change_pending = false;
@@ -363,10 +408,16 @@ int register_virtio_device(struct virtio_device *dev)
363
408
*/
364
409
err = device_add (& dev -> dev );
365
410
if (err )
366
- ida_simple_remove (& virtio_index_ida , dev -> index );
411
+ goto out_of_node_put ;
412
+
413
+ return 0 ;
414
+
415
+ out_of_node_put :
416
+ of_node_put (dev -> dev .of_node );
417
+ out_ida_remove :
418
+ ida_simple_remove (& virtio_index_ida , dev -> index );
367
419
out :
368
- if (err )
369
- virtio_add_status (dev , VIRTIO_CONFIG_S_FAILED );
420
+ virtio_add_status (dev , VIRTIO_CONFIG_S_FAILED );
370
421
return err ;
371
422
}
372
423
EXPORT_SYMBOL_GPL (register_virtio_device );
0 commit comments