@@ -85,6 +85,102 @@ int of_reconfig_notify(unsigned long action, void *p)
85
85
return notifier_to_errno (rc );
86
86
}
87
87
88
+ /*
89
+ * of_reconfig_get_state_change() - Returns new state of device
90
+ * @action - action of the of notifier
91
+ * @arg - argument of the of notifier
92
+ *
93
+ * Returns the new state of a device based on the notifier used.
94
+ * Returns 0 on device going from enabled to disabled, 1 on device
95
+ * going from disabled to enabled and -1 on no change.
96
+ */
97
+ int of_reconfig_get_state_change (unsigned long action , void * arg )
98
+ {
99
+ struct device_node * dn ;
100
+ struct property * prop , * old_prop ;
101
+ struct of_prop_reconfig * pr ;
102
+ int is_status , status_state , old_status_state , prev_state , new_state ;
103
+
104
+ /* figure out if a device should be created or destroyed */
105
+ dn = NULL ;
106
+ prop = old_prop = NULL ;
107
+ switch (action ) {
108
+ case OF_RECONFIG_ATTACH_NODE :
109
+ case OF_RECONFIG_DETACH_NODE :
110
+ dn = arg ;
111
+ prop = of_find_property (dn , "status" , NULL );
112
+ break ;
113
+ case OF_RECONFIG_ADD_PROPERTY :
114
+ case OF_RECONFIG_REMOVE_PROPERTY :
115
+ pr = arg ;
116
+ dn = pr -> dn ;
117
+ prop = pr -> prop ;
118
+ break ;
119
+ case OF_RECONFIG_UPDATE_PROPERTY :
120
+ pr = arg ;
121
+ dn = pr -> dn ;
122
+ prop = pr -> prop ;
123
+ old_prop = pr -> old_prop ;
124
+ break ;
125
+ default :
126
+ return OF_RECONFIG_NO_CHANGE ;
127
+ }
128
+
129
+ is_status = 0 ;
130
+ status_state = -1 ;
131
+ old_status_state = -1 ;
132
+ prev_state = -1 ;
133
+ new_state = -1 ;
134
+
135
+ if (prop && !strcmp (prop -> name , "status" )) {
136
+ is_status = 1 ;
137
+ status_state = !strcmp (prop -> value , "okay" ) ||
138
+ !strcmp (prop -> value , "ok" );
139
+ if (old_prop )
140
+ old_status_state = !strcmp (old_prop -> value , "okay" ) ||
141
+ !strcmp (old_prop -> value , "ok" );
142
+ }
143
+
144
+ switch (action ) {
145
+ case OF_RECONFIG_ATTACH_NODE :
146
+ prev_state = 0 ;
147
+ /* -1 & 0 status either missing or okay */
148
+ new_state = status_state != 0 ;
149
+ break ;
150
+ case OF_RECONFIG_DETACH_NODE :
151
+ /* -1 & 0 status either missing or okay */
152
+ prev_state = status_state != 0 ;
153
+ new_state = 0 ;
154
+ break ;
155
+ case OF_RECONFIG_ADD_PROPERTY :
156
+ if (is_status ) {
157
+ /* no status property -> enabled (legacy) */
158
+ prev_state = 1 ;
159
+ new_state = status_state ;
160
+ }
161
+ break ;
162
+ case OF_RECONFIG_REMOVE_PROPERTY :
163
+ if (is_status ) {
164
+ prev_state = status_state ;
165
+ /* no status property -> enabled (legacy) */
166
+ new_state = 1 ;
167
+ }
168
+ break ;
169
+ case OF_RECONFIG_UPDATE_PROPERTY :
170
+ if (is_status ) {
171
+ prev_state = old_status_state != 0 ;
172
+ new_state = status_state != 0 ;
173
+ }
174
+ break ;
175
+ }
176
+
177
+ if (prev_state == new_state )
178
+ return OF_RECONFIG_NO_CHANGE ;
179
+
180
+ return new_state ? OF_RECONFIG_CHANGE_ADD : OF_RECONFIG_CHANGE_REMOVE ;
181
+ }
182
+ EXPORT_SYMBOL_GPL (of_reconfig_get_state_change );
183
+
88
184
int of_property_notify (int action , struct device_node * np ,
89
185
struct property * prop , struct property * oldprop )
90
186
{
0 commit comments