aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPantelis Antoniou <pantelis.antoniou@konsulko.com>2014-10-28 16:33:53 -0400
committerGrant Likely <grant.likely@linaro.org>2014-11-24 17:24:54 -0500
commitb53a2340d0d30468b7315992ba77fe188c3bc5c8 (patch)
tree25c48e891b110f1a84f442e0e5727d9a58abc374 /drivers
parentda56d04c806a3e9986c66a061d7363ca3157c37b (diff)
of/reconfig: Add of_reconfig_get_state_change() of notifier helper.
Introduce of_reconfig_get_state_change() which allows an of notifier to query about device state changes. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Signed-off-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/of/dynamic.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 661ad2f5c00c..6659c39ab3aa 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -85,6 +85,102 @@ int of_reconfig_notify(unsigned long action, void *p)
85 return notifier_to_errno(rc); 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 */
97int 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}
182EXPORT_SYMBOL_GPL(of_reconfig_get_state_change);
183
88int of_property_notify(int action, struct device_node *np, 184int of_property_notify(int action, struct device_node *np,
89 struct property *prop, struct property *oldprop) 185 struct property *prop, struct property *oldprop)
90{ 186{