serdev: Introduce devm_serdev_device_open()
authorAndrey Smirnov <andrew.smirnov@gmail.com>
Thu, 9 Nov 2017 16:05:53 +0000 (08:05 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 28 Nov 2017 14:32:32 +0000 (15:32 +0100)
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()).

Cc: linux-kernel@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: Rob Herring <robh@kernel.org>
Cc: cphealy@gmail.com
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
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: Greg Kroah-Hartman <gregkh@linuxfoundation.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);