diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2017-12-20 22:51:15 -0800 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2018-01-08 10:08:34 +0000 |
commit | 2cb67d20cdea1f4da60bbe073d32bd2ba11c22ad (patch) | |
tree | ac8cdcf7bc28551c03dc2d8282e4500836c14eea | |
parent | c5ff7de262b6e92ec88a20ea0a0244c29ccdc764 (diff) | |
download | op-kernel-dev-2cb67d20cdea1f4da60bbe073d32bd2ba11c22ad.zip op-kernel-dev-2cb67d20cdea1f4da60bbe073d32bd2ba11c22ad.tar.gz |
serdev: Introduce devm_serdev_device_open()
Add code implementing managed version of serdev_device_open() for
serdev device drivers that "open" the device during driver's lifecycle
only once (e.g. opened in .probe() and closed in .remove()).
Acked-by: Philippe Ombredanne <pombredanne@nexb.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r-- | Documentation/driver-model/devres.txt | 3 | ||||
-rw-r--r-- | drivers/tty/serdev/core.c | 27 | ||||
-rw-r--r-- | include/linux/serdev.h | 1 |
3 files changed, 31 insertions, 0 deletions
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index c180045..7c1bb3d 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -384,6 +384,9 @@ RESET devm_reset_control_get() devm_reset_controller_register() +SERDEV + devm_serdev_device_open() + SLAVE DMA ENGINE devm_acpi_dma_controller_register() diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 34050b4..28133db 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -132,6 +132,33 @@ void serdev_device_close(struct serdev_device *serdev) } EXPORT_SYMBOL_GPL(serdev_device_close); +static void devm_serdev_device_release(struct device *dev, void *dr) +{ + serdev_device_close(*(struct serdev_device **)dr); +} + +int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev) +{ + struct serdev_device **dr; + int ret; + + dr = devres_alloc(devm_serdev_device_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + ret = serdev_device_open(serdev); + if (ret) { + devres_free(dr); + return ret; + } + + *dr = serdev; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_serdev_device_open); + void serdev_device_write_wakeup(struct serdev_device *serdev) { complete(&serdev->write_comp); diff --git a/include/linux/serdev.h b/include/linux/serdev.h index e69402d..9929063 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -193,6 +193,7 @@ static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl, int serdev_device_open(struct serdev_device *); void serdev_device_close(struct serdev_device *); +int devm_serdev_device_open(struct device *, struct serdev_device *); unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); void serdev_device_set_flow_control(struct serdev_device *, bool); int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); |