of: conditional status property
Add dynamic aspect to the status property. Conditional status references another property and changes availability of the device node based on the value of the referenced property. This allows to manipulate the device tree at boot. For example, change availability of certain devices based on a property set by the bootloader under "/chosen" node. Syntax allows partial match of specified property value by adding keyword "contains" in front of values list. Propagation of (CR). Change-Id: I3a69fe1b95c2e140feff54edb7048a5610a94d0c Signed-off-by: Konstantin Makariev <hcv867@motorola.com> Reviewed-on: https://gerrit.mot.com/1439246 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Konstantin Makariev <kmakariev@motorola.com> Submit-Approved: Jira Key Reviewed-on: https://gerrit.mot.com/1509716 Reviewed-by: Wang Wang <wangwang1@lenovo.com>
This commit is contained in:
1 parent
5ff82102f6
commit
c0bbf0b613
1 file changed
+54
-7
+54
-7
@@ -599,24 +599,71 @@ EXPORT_SYMBOL(of_machine_is_compatible);
|
||||
*
|
||||
* @device: Node to check for availability, with locks already held
|
||||
*
|
||||
* Returns true if the status property is absent or set to "okay" or "ok",
|
||||
* Returns true if the status property
|
||||
* -- is absent or set to "okay" or "ok",
|
||||
* -- refers to another property using string list as following
|
||||
* status = <path>, <okay property>, [<contains>,] <value1>[, <value2>...];
|
||||
* and at least one <value> in the list of values matches
|
||||
* value of /<path>/<okay property>.
|
||||
* Partial matches accepted when "contains" provided.
|
||||
* false otherwise
|
||||
*/
|
||||
static bool __of_device_is_available(const struct device_node *device)
|
||||
{
|
||||
const char *status;
|
||||
int statlen;
|
||||
struct property *pp;
|
||||
struct device_node *np;
|
||||
const char *val, *status;
|
||||
const char *okay_prop_name, *okay_val;
|
||||
bool found;
|
||||
int len, operation;
|
||||
|
||||
if (!device)
|
||||
return false;
|
||||
|
||||
status = __of_get_property(device, "status", &statlen);
|
||||
if (status == NULL)
|
||||
pp = __of_find_property(device, "status", &len);
|
||||
if (pp == NULL)
|
||||
return true;
|
||||
|
||||
if (statlen > 0) {
|
||||
if (!strcmp(status, "okay") || !strcmp(status, "ok"))
|
||||
status = pp->value;
|
||||
|
||||
if (len > 0) {
|
||||
if (!strncmp(status, "ok", 2))
|
||||
return true;
|
||||
|
||||
if (!strncmp(status, "disable", 7))
|
||||
return false;
|
||||
|
||||
np = __of_find_node_by_full_path(of_root, status);
|
||||
if (!np)
|
||||
return false;
|
||||
|
||||
okay_prop_name = of_prop_next_string(pp, status);
|
||||
if (!okay_prop_name)
|
||||
return false;
|
||||
|
||||
okay_val = __of_get_property(np, okay_prop_name, &len);
|
||||
if (okay_val == NULL || len <= 0)
|
||||
return false;
|
||||
|
||||
val = okay_prop_name;
|
||||
operation = 0;
|
||||
found = false;
|
||||
while ((val = of_prop_next_string(pp, val))) {
|
||||
if (!operation) {
|
||||
operation++;
|
||||
if (!strcmp(val, "contains")) {
|
||||
operation++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (operation == 1) {
|
||||
if (!strcmp(val, okay_val))
|
||||
found = true;
|
||||
} else if (strstr(okay_val, val))
|
||||
found = true;
|
||||
if (found)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in new issue
Block a user