参照元

説明

引数

返り値

参考

実装

/**
 * pinctrl_register() - register a pin controller device
 * @pctldesc: descriptor for this pin controller
 * @dev: parent device for this pin controller
 * @driver_data: private pin controller data for this pin controller
 */
struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
                                    struct device *dev, void *driver_data)
{
        struct pinctrl_dev *pctldev;
        int ret;
        if (!pctldesc)
                return ERR_PTR(-EINVAL);
        if (!pctldesc->name)
                return ERR_PTR(-EINVAL);
        pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL);
        if (pctldev == NULL) {
                dev_err(dev, "failed to alloc struct pinctrl_dev\n");
                return ERR_PTR(-ENOMEM);
        }
        /* Initialize pin control device struct */
        pctldev->owner = pctldesc->owner;
        pctldev->desc = pctldesc;
        pctldev->driver_data = driver_data;
        INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
        INIT_LIST_HEAD(&pctldev->gpio_ranges);
        pctldev->dev = dev;
        mutex_init(&pctldev->mutex);
        /* check core ops for sanity */
        ret = pinctrl_check_ops(pctldev);
        if (ret) {
                dev_err(dev, "pinctrl ops lacks necessary functions\n");
                goto out_err;
        }
        /* If we're implementing pinmuxing, check the ops for sanity */
        if (pctldesc->pmxops) {
                ret = pinmux_check_ops(pctldev);
                if (ret)
                        goto out_err;
        }
        /* If we're implementing pinconfig, check the ops for sanity */
        if (pctldesc->confops) {
                ret = pinconf_check_ops(pctldev);
                if (ret)
                        goto out_err;
        }
        /* Register all the pins */
        dev_dbg(dev, "try to register %d pins ...\n",  pctldesc->npins);
        ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);
        if (ret) {
                dev_err(dev, "error during pin registration\n");
                pinctrl_free_pindescs(pctldev, pctldesc->pins,
                                      pctldesc->npins);
                goto out_err;
        }
        mutex_lock(&pinctrldev_list_mutex);
        list_add_tail(&pctldev->node, &pinctrldev_list);
        mutex_unlock(&pinctrldev_list_mutex);
        pctldev->p = pinctrl_get(pctldev->dev);
        if (!IS_ERR(pctldev->p)) {
                pctldev->hog_default =
                        pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT);
                if (IS_ERR(pctldev->hog_default)) {
                        dev_dbg(dev, "failed to lookup the default state\n");
                } else {
                        if (pinctrl_select_state(pctldev->p,
                                                pctldev->hog_default))
                                dev_err(dev,
                                        "failed to select default state\n");
                }
                pctldev->hog_sleep =
                        pinctrl_lookup_state(pctldev->p,
                                                    PINCTRL_STATE_SLEEP);
                if (IS_ERR(pctldev->hog_sleep))
                        dev_dbg(dev, "failed to lookup the sleep state\n");
        }

        pinctrl_init_device_debugfs(pctldev);
        return pctldev;

out_err:
        mutex_destroy(&pctldev->mutex);
        kfree(pctldev);
        return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(pinctrl_register);

コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-05-19 (木) 10:28:57