of_device_is_compatible

来源:互联网 发布:淘宝怎样选关键词 编辑:程序博客网 时间:2024/05/29 21:18
在acpi mode下可以通过acpi_match_device 和 acpi_dev_found 知道当前匹配了哪个apci id,同样对dts则使用
of_device_is_compatible 来知道当前dts是匹配那个dts id了。例如下面的例子

    if (dev_of_node(dsaf_dev->dev)) {
        if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1"))
            dsaf_dev->dsaf_ver = AE_VERSION_1;
        else
            dsaf_dev->dsaf_ver = AE_VERSION_2;
    }
源码如下:
int of_device_is_compatible(const struct device_node *device,
        const char *compat)
{
    unsigned long flags;
    int res;

    raw_spin_lock_irqsave(&devtree_lock, flags);
    res = __of_device_is_compatible(device, compat, NULL, NULL);
    raw_spin_unlock_irqrestore(&devtree_lock, flags);
    return res;
}

static int __of_device_is_compatible(const struct device_node *device,
                     const char *compat, const char *type, const char *name)
{
    struct property *prop;
    const char *cp;
    int index = 0, score = 0;

    /* Compatible match has highest priority */
//先比较Compatible,然后比较type,最后比较name
    if (compat && compat[0]) {
        prop = __of_find_property(device, "compatible", NULL);
        for (cp = of_prop_next_string(prop, NULL); cp;
             cp = of_prop_next_string(prop, cp), index++) {
            if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
                score = INT_MAX/2 - (index << 2);
                break;
            }
        }
        if (!score)
            return 0;
    }

    /* Matching type is better than matching name */
    if (type && type[0]) {
        if (!device->type || of_node_cmp(type, device->type))
            return 0;
        score += 2;
    }

    /* Matching name is a bit better than not */
    if (name && name[0]) {
        if (!device->name || of_node_cmp(name, device->name))
            return 0;
        score++;
    }

    return score;
}
这里通过__of_find_property 拿到这个device的所有property
static struct property *__of_find_property(const struct device_node *np,
                       const char *name, int *lenp)
{
    struct property *pp;

    if (!np)
        return NULL;

    for (pp = np->properties; pp; pp = pp->next) {
        if (of_prop_cmp(pp->name, name) == 0) {
            if (lenp)
                *lenp = pp->length;
            break;
        }
    }

    return pp;
}


原创粉丝点击