lkml.org 
[lkml]   [2018]   [Jun]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v2 07/24] serdev: Allows dynamic creation of devices via sysfs
Date
Allow creating and deleting devices via sysfs. Devices created will be
matched to serdev drivers via modalias (the string provided by the user)
and deleted via their name. Eg:

# Create device
root@qt5022:~# echo ttydev > /sys/bus/serial/devices/serial0/new_device

# Delete device
root@qt5022:~#
echo serial0-0 > /sys/bus/serial/devices/serial0/delete_device

Cc: Rob Herring <robh@kernel.org>
Cc: Johan Hovold <johan@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
drivers/tty/serdev/core.c | 69 +++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)

diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 2c79f47fc0db..5df01d8cf307 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -75,7 +75,76 @@ static void serdev_ctrl_release(struct device *dev)
kfree(ctrl);
}

+static ssize_t
+new_device_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct serdev_controller *ctrl = to_serdev_controller(dev);
+ struct serdev_device *serdev;
+ char *nline;
+ int len;
+ int err;
+
+ serdev = serdev_device_alloc(ctrl);
+ if (!serdev)
+ return -ENOMEM;
+
+ nline = strchr(buf, '\n');
+ if (nline)
+ len = nline - buf;
+ else
+ len = strlen(buf);
+ len = min(SERDEV_NAME_SIZE - 1, len);
+
+ strncpy(serdev->modalias, buf, len);
+ serdev->modalias[len] = '\0';
+
+ err = serdev_device_add(serdev);
+ if (err) {
+ serdev_device_put(serdev);
+ return err;
+ }
+
+ return count;
+}
+static DEVICE_ATTR_WO(new_device);
+
+static ssize_t
+delete_device_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct serdev_controller *ctrl = to_serdev_controller(dev);
+ struct serdev_device *serdev = ctrl->serdev;
+ char *nline;
+ int len;
+
+ nline = strchr(buf, '\n');
+ if (nline)
+ len = nline - buf;
+ else
+ len = strlen(buf);
+ len = min(SERDEV_NAME_SIZE - 1, len);
+
+ if (!ctrl->serdev ||
+ strncmp(dev_name(&serdev->dev), buf, len))
+ return -ENODEV;
+
+ serdev_device_remove(serdev);
+
+ return count;
+}
+static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, 0200, NULL,
+ delete_device_store);
+
+static struct attribute *serdev_ctrl_attrs[] = {
+ &dev_attr_new_device.attr,
+ &dev_attr_delete_device.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(serdev_ctrl);
+
static const struct device_type serdev_ctrl_type = {
+ .groups = serdev_ctrl_groups,
.release = serdev_ctrl_release,
};

--
2.17.1
\
 
 \ /
  Last update: 2018-06-11 13:53    [W:0.165 / U:0.352 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site