diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2016-05-25 08:09:31 +0300 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-05-31 11:27:19 +0300 |
commit | cd8f61f1e52b33766639e28a042d717d1e069d4f (patch) | |
tree | 801bb36205960e6c26028de592a15a2bd54d36c6 /drivers/pinctrl/core.c | |
parent | cf9d994dcf00c09c73eb686e239ab6449a248719 (diff) | |
download | linux-cd8f61f1e52b33766639e28a042d717d1e069d4f.tar.xz |
pinctrl: copy per-pin driver private data to struct pin_desc
Currently, struct pinctrl_pin_desc can have per-pin driver private
data, but it is not copied to struct pin_desc.
For a driver with sparse pin space, for-loop search like below would
be necessary in order to get the driver-specific data for a desired
pin number.
for (i = 0; i < pctldev->desc->npins; i++)
if (pin_number == pctldev->desc->pins[i].number)
return pctldev->desc->pins[i].drv_data;
This is not efficient for a driver with a large number of pins.
So, copy the data to struct pin_desc when each pin is registered
for the faster radix tree lookup.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/core.c')
-rw-r--r-- | drivers/pinctrl/core.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 03c08c156744..fb38e208f32d 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -225,13 +225,14 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, } static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, - unsigned number, const char *name) + const struct pinctrl_pin_desc *pin) { struct pin_desc *pindesc; - pindesc = pin_desc_get(pctldev, number); + pindesc = pin_desc_get(pctldev, pin->number); if (pindesc != NULL) { - dev_err(pctldev->dev, "pin %d already registered\n", number); + dev_err(pctldev->dev, "pin %d already registered\n", + pin->number); return -EINVAL; } @@ -245,10 +246,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->pctldev = pctldev; /* Copy basic pin info */ - if (name) { - pindesc->name = name; + if (pin->name) { + pindesc->name = pin->name; } else { - pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number); + pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number); if (pindesc->name == NULL) { kfree(pindesc); return -ENOMEM; @@ -256,9 +257,11 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->dynamic_name = true; } - radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc); + pindesc->drv_data = pin->drv_data; + + radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); pr_debug("registered pin %d (%s) on %s\n", - number, pindesc->name, pctldev->desc->name); + pin->number, pindesc->name, pctldev->desc->name); return 0; } @@ -270,8 +273,7 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev, int ret = 0; for (i = 0; i < num_descs; i++) { - ret = pinctrl_register_one_pin(pctldev, - pins[i].number, pins[i].name); + ret = pinctrl_register_one_pin(pctldev, &pins[i]); if (ret) return ret; } |