[SLOF] [PATCH 3/3] fdt: Delete nodes of devices removed between boot and CAS

Greg Kurz groug at kaod.org
Thu Feb 6 05:21:48 AEDT 2020


We recently fixed node creation at CAS in order to support early hotplug of
devices between boot and CAS. Let's handle node removal now to support early
hot *un*plug of devices.

This is done in three phases:

1) all nodes from the boot time FDT are added a "slof,present-at-boot"
   property

2) during pass 0 of (fdt-fix-cas-node) all nodes from the CAS FDT are added
   a "slof,present-at-cas" property

3) loop on all nodes in the DT and delete the ones that only have the
   "slof,present-at-boot" property, and any alias they might have. In
   the  same time, "slof,present-at-cas" properties are converted into
   "slof,present-at-boot" to allow further node removal in case of a
   subsequent device unplug and CAS sequence before quiesce (linux
   doesn't do that but it isn't explicitely forbidden by the spec).

Signed-off-by: Greg Kurz <groug at kaod.org>
---
 board-qemu/slof/fdt.fs |   94 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/board-qemu/slof/fdt.fs b/board-qemu/slof/fdt.fs
index 66f8fe74d9dd..1125f6702435 100644
--- a/board-qemu/slof/fdt.fs
+++ b/board-qemu/slof/fdt.fs
@@ -198,6 +198,8 @@ fdt-check-header
     decode-int dup fdt-create-dec fdt-create-enc 2drop
   THEN
 
+  0 0 s" slof,present-at-boot" property
+
   finish-device  
 ;
 
@@ -514,6 +516,9 @@ r> drop
     swap			( newnode? a1 )
 
     fdt-debug IF ." Current  now: " pwd  get-node ."  = " . cr THEN
+    fdt-cas-pass 0= IF
+	0 0 s" slof,present-at-cas" property
+    THEN
     BEGIN
 	fdt-next-tag dup OF_DT_END_NODE <>
     WHILE
@@ -584,8 +589,97 @@ r> drop
     THEN
 ;
 
+: alias-dev-path ( xt -- dev-path len )
+    link> execute decode-string	2swap 2drop
+;
+
+: alias-name ( xt -- alias-name len )
+    link> >name name>string
+;
+
+: fdt-cas-alias-obsolete? ( node xt -- true|false )
+    alias-dev-path rot node>path str=
+;
+
+: (fdt-cas-delete-obsolete-aliases) ( node xt -- )
+    dup IF
+	dup @ 2 pick swap                 ( node xt node next-xt )
+	recurse                           ( node xt )
+	2dup fdt-cas-alias-obsolete? IF
+	    dup alias-name                ( node xt alias-name len )
+	    fdt-debug IF ."    Deleting alias " 2dup type cr THEN
+	    delete-property               ( node xt )
+	THEN
+    THEN
+    2drop
+;
+
+: fdt-cas-delete-obsolete-aliases ( node -- )
+    s" /aliases" find-node dup IF
+                                          ( node aliases )
+	get-node >r
+	dup set-node
+
+	node>properties @ cell+ @         ( node xt )
+	over swap                         ( node node xt )
+	(fdt-cas-delete-obsolete-aliases) ( node )
+
+	r> set-node
+    THEN
+    drop
+;
+
+: fdt-cas-node-obsolete? ( node -- true|false)
+    s" slof,present-at-cas" 2 pick get-package-property IF
+	s" slof,present-at-boot" 2 pick get-package-property IF
+	    \ Node not coming from the QEMU
+	    FALSE
+	ELSE
+	    \ Device got removed since last boot or CAS
+	    2drop
+	    TRUE
+	THEN
+    ELSE
+	2drop                                   ( node )
+
+	get-node >r
+	dup set-node
+
+	\ Any device present in the CAS FDT is now considered as if it was
+	\ present at boot, ie. cold plugged. This allows a subsequent CAS
+	\ to remove the node from the DT if the device gets unplugged in
+	\ between).
+	s" slof,present-at-cas" delete-property
+	0 0 s" slof,present-at-boot" property
+
+	r> set-node
+	FALSE
+    THEN
+    nip
+;
+
+: (fdt-cas-search-obsolete-nodes) ( start node -- )
+    dup IF
+	dup child 2 pick swap recurse
+	dup peer 2 pick swap recurse      ( start node )
+
+	fdt-debug IF dup ." Inspecting node: " dup .node ." = " . cr THEN
+	dup fdt-cas-node-obsolete? IF
+	    fdt-debug IF ."    Deleting node" cr THEN
+	    dup fdt-cas-delete-obsolete-aliases
+	    dup delete-node
+	THEN
+    THEN
+    2drop
+;
+
+: fdt-cas-delete-obsolete-nodes ( start -- )
+    s" /" find-device get-node (fdt-cas-search-obsolete-nodes)
+;
+
 : fdt-fix-cas-node ( start -- )
     0 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Add phandles
+    dup fdt-cas-delete-obsolete-nodes             \ Delete removed devices
     1 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Patch+add other properties
     2 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Delete phandles from pass 0
     drop



More information about the SLOF mailing list