参照元

説明

引数

返り値

参考

実装

static int __of_parse_phandle_with_args(const struct device_node *np,
                                        const char *list_name,
                                        const char *cells_name,
                                        int cell_count, int index,
                                        struct of_phandle_args *out_args)
{
        const __be32 *list, *list_end;
        int rc = 0, size, cur_index = 0;
        uint32_t count = 0;
        struct device_node *node = NULL;
        phandle phandle;
        /* Retrieve the phandle list property */
        list = of_get_property(np, list_name, &size);
        if (!list)
                return -ENOENT;
        list_end = list + size / sizeof(*list);
        /* Loop over the phandles until all the requested entry is found */
        while (list < list_end) {
                rc = -EINVAL;
                count = 0;

                /*
                 * If phandle is 0, then it is an empty entry with no
                 * arguments.  Skip forward to the next entry.
                 */
                phandle = be32_to_cpup(list++);
                if (phandle) {
                        /*
                         * Find the provider node and parse the #*-cells
                         * property to determine the argument length.
                         *
                         * This is not needed if the cell count is hard-coded
                         * (i.e. cells_name not set, but cell_count is set),
                         * except when we're going to return the found node
                         * below.
                         */
                        if (cells_name || cur_index == index) {
                                node = of_find_node_by_phandle(phandle);
                                if (!node) {
                                        pr_err("%s: could not find phandle\n",
                                                np->full_name);
                                        goto err;
                                }
                        }

                        if (cells_name) {
                                if (of_property_read_u32(node, cells_name,
                                                         &count)) {
                                        pr_err("%s: could not get %s for %s\n",
                                                np->full_name, cells_name,
                                                node->full_name);
                                        goto err;
                                }
                        } else {
                                count = cell_count;
                        }

                        /*
                         * Make sure that the arguments actually fit in the
                         * remaining property data length
                         */
                        if (list + count > list_end) {
                                pr_err("%s: arguments longer than property\n",
                                         np->full_name);
                                goto err;
                        }
                }

                /*
                 * All of the error cases above bail out of the loop, so at
                 * this point, the parsing is successful. If the requested
                 * index matches, then fill the out_args structure and return,
                 * or return -ENOENT for an empty entry.
                 */
                rc = -ENOENT;
                if (cur_index == index) {
                        if (!phandle)
                                goto err;

                        if (out_args) {
                                int i;
                                if (WARN_ON(count > MAX_PHANDLE_ARGS))
                                        count = MAX_PHANDLE_ARGS;
                                out_args->np = node;
                                out_args->args_count = count;
                                for (i = 0; i < count; i++)
                                        out_args->args[i] = be32_to_cpup(list++);
                        } else {
                                of_node_put(node);
                        }
                        /* Found it! return success */
                        return 0;
                }

                of_node_put(node);
                node = NULL;
                list += count;
                cur_index++;
        }

        /*
         * Unlock node before returning result; will be one of:
         * -ENOENT : index is for empty phandle
         * -EINVAL : parsing error on data
         * [1..n]  : Number of phandle (count mode; when index = -1)
         */
        rc = index < 0 ? cur_index : -ENOENT;
 err:
        if (node)
                of_node_put(node);
        return rc;
}

コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-03-07 (月) 11:21:31