diff options
Diffstat (limited to 'drivers/pinctrl/core.c')
-rw-r--r-- | drivers/pinctrl/core.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index f67a8b7a4e18..98d2a1bb44cb 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1872,6 +1872,69 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) } EXPORT_SYMBOL_GPL(pinctrl_unregister); +static void devm_pinctrl_dev_release(struct device *dev, void *res) +{ + struct pinctrl_dev *pctldev = *(struct pinctrl_dev **)res; + + pinctrl_unregister(pctldev); +} + +static int devm_pinctrl_dev_match(struct device *dev, void *res, void *data) +{ + struct pctldev **r = res; + + if (WARN_ON(!r || !*r)) + return 0; + + return *r == data; +} + +/** + * devm_pinctrl_register() - Resource managed version of pinctrl_register(). + * @dev: parent device for this pin controller + * @pctldesc: descriptor for this pin controller + * @driver_data: private pin controller data for this pin controller + * + * Returns an error pointer if pincontrol register failed. Otherwise + * it returns valid pinctrl handle. + * + * The pinctrl device will be automatically released when the device is unbound. + */ +struct pinctrl_dev *devm_pinctrl_register(struct device *dev, + struct pinctrl_desc *pctldesc, + void *driver_data) +{ + struct pinctrl_dev **ptr, *pctldev; + + ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + pctldev = pinctrl_register(pctldesc, dev, driver_data); + if (IS_ERR(pctldev)) { + devres_free(ptr); + return pctldev; + } + + *ptr = pctldev; + devres_add(dev, ptr); + + return pctldev; +} +EXPORT_SYMBOL_GPL(devm_pinctrl_register); + +/** + * devm_pinctrl_unregister() - Resource managed version of pinctrl_unregister(). + * @dev: device for which which resource was allocated + * @pctldev: the pinctrl device to unregister. + */ +void devm_pinctrl_unregister(struct device *dev, struct pinctrl_dev *pctldev) +{ + WARN_ON(devres_release(dev, devm_pinctrl_dev_release, + devm_pinctrl_dev_match, pctldev)); +} +EXPORT_SYMBOL_GPL(devm_pinctrl_unregister); + static int __init pinctrl_init(void) { pr_info("initialized pinctrl subsystem\n"); |