serdev: Introduce devm_serdev_device_open()
authorAndrey Smirnov <andrew.smirnov@gmail.com>
Thu, 21 Dec 2017 06:51:15 +0000 (22:51 -0800)
committerLee Jones <lee.jones@linaro.org>
Mon, 8 Jan 2018 10:08:34 +0000 (10:08 +0000)
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>
Documentation/driver-model/devres.txt
drivers/tty/serdev/core.c
include/linux/serdev.h

index c180045eb43b190beccc1072a7285f6f5de5bf34..7c1bb3d0c2229363fcc2eb5d729f911f59c258d9 100644 (file)
@@ -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()
 
index 34050b439c1fe75e9e21da2c33d0c73c35d4a9f7..28133dbd2808fde58201d80f822249aeedcabdeb 100644 (file)
@@ -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);
index e69402d4a8aecbdc6fe4a40e8ad7e01957badbd6..9929063bd45db29ec00f1919cab0b27c0db9fe9b 100644 (file)
@@ -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);