of_device_id 用于device和driver的match,其在kernel\linux-3.10.y\include\linux\mod_devicetable.h中定义
/* Struct used for matching a device */
struct of_device_id
{
char name[32];
char type[32];
char compatible[128]; //用于device和driver的match
const void *data;
};
const struct of_device_id *of_match_device(const struct of_device_id *matches,
const struct device *dev)
{
if ((!matches) || (!dev->of_node))
return NULL;
return of_match_node(matches, dev->of_node);
}
const struct of_device_id *of_match_node(const struct of_device_id *matches,
const struct device_node *node)
{
const struct of_device_id *match;
unsigned long flags;
raw_spin_lock_irqsave(&devtree_lock, flags);
match = __of_match_node(matches, node);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return match;
}
static
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
const struct device_node *node)
{
if (!matches)
return NULL;
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
int match = 1;
if (matches->name[0])
match &= node->name
&& !strcmp(matches->name, node->name);
if (matches->type[0])
match &= node->type
&& !strcmp(matches->type, node->type);
if (matches->compatible[0])
match &= __of_device_is_compatible(node,
matches->compatible);
if (match)
return matches;
matches++;
}
return NULL;
}
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
static int __of_device_is_compatible(const struct device_node *device,
const char *compat)
{
const char* cp;
int cplen, l;
cp = __of_get_property(device, "compatible", &cplen);
if (cp == NULL)
return 0;
while (cplen > 0) {
if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
return 1;
l = strlen(cp) + 1;
cp += l;
cplen -= l;
}
return 0;
}