[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180529131014.18641-8-ricardo.ribalda@gmail.com>
Date: Tue, 29 May 2018 15:10:02 +0200
From: Ricardo Ribalda Delgado <ricardo.ribalda@...il.com>
To: linux-kernel@...r.kernel.org, linux-serial@...r.kernel.org
Cc: Ricardo Ribalda Delgado <ricardo.ribalda@...il.com>,
Rob Herring <robh@...nel.org>, Johan Hovold <johan@...nel.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Jiri Slaby <jslaby@...e.com>
Subject: [PATCH 07/19] serdev: Allows dynamic creation of devices via sysfs
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@...022:~# echo ttydev > /sys/bus/serial/devices/serial0/new_device
# Delete device
root@...022:~#
echo serial0-0 > /sys/bus/serial/devices/serial0/delete_device
Cc: Rob Herring <robh@...nel.org>
Cc: Johan Hovold <johan@...nel.org>
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: Jiri Slaby <jslaby@...e.com>
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@...il.com>
---
drivers/tty/serdev/core.c | 60 +++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 2c79f47fc0db..e695fa649a6d 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -75,7 +75,67 @@ 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;
+ int err;
+ char *nline;
+
+ serdev = serdev_device_alloc(ctrl);
+ if (!serdev)
+ return -ENOMEM;
+
+ nline = strchr(buf, '\n');
+ if (nline)
+ *nline = '\0';
+
+ strncpy(serdev->modalias, buf, SERDEV_NAME_SIZE);
+
+ 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;
+
+ nline = strchr(buf, '\n');
+ if (nline)
+ *nline = '\0';
+
+ if (!ctrl->serdev ||
+ strncmp(dev_name(&serdev->dev), buf, SERDEV_NAME_SIZE))
+ 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.0
Powered by blists - more mailing lists