Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / android / timed_output.c
diff --git a/kernel/drivers/staging/android/timed_output.c b/kernel/drivers/staging/android/timed_output.c
new file mode 100644 (file)
index 0000000..b41429f
--- /dev/null
@@ -0,0 +1,120 @@
+/* drivers/misc/timed_output.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "timed_output: " fmt
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+
+#include "timed_output.h"
+
+static struct class *timed_output_class;
+static atomic_t device_count;
+
+static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       struct timed_output_dev *tdev = dev_get_drvdata(dev);
+       int remaining = tdev->get_time(tdev);
+
+       return sprintf(buf, "%d\n", remaining);
+}
+
+static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t size)
+{
+       struct timed_output_dev *tdev = dev_get_drvdata(dev);
+       int value;
+       int rc;
+
+       rc = kstrtoint(buf, 0, &value);
+       if (rc != 0)
+               return -EINVAL;
+
+       tdev->enable(tdev, value);
+
+       return size;
+}
+static DEVICE_ATTR_RW(enable);
+
+static struct attribute *timed_output_attrs[] = {
+       &dev_attr_enable.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(timed_output);
+
+static int create_timed_output_class(void)
+{
+       if (!timed_output_class) {
+               timed_output_class = class_create(THIS_MODULE, "timed_output");
+               if (IS_ERR(timed_output_class))
+                       return PTR_ERR(timed_output_class);
+               atomic_set(&device_count, 0);
+               timed_output_class->dev_groups = timed_output_groups;
+       }
+
+       return 0;
+}
+
+int timed_output_dev_register(struct timed_output_dev *tdev)
+{
+       int ret;
+
+       if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time)
+               return -EINVAL;
+
+       ret = create_timed_output_class();
+       if (ret < 0)
+               return ret;
+
+       tdev->index = atomic_inc_return(&device_count);
+       tdev->dev = device_create(timed_output_class, NULL,
+               MKDEV(0, tdev->index), NULL, "%s", tdev->name);
+       if (IS_ERR(tdev->dev))
+               return PTR_ERR(tdev->dev);
+
+       dev_set_drvdata(tdev->dev, tdev);
+       tdev->state = 0;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(timed_output_dev_register);
+
+void timed_output_dev_unregister(struct timed_output_dev *tdev)
+{
+       tdev->enable(tdev, 0);
+       device_destroy(timed_output_class, MKDEV(0, tdev->index));
+}
+EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
+
+static int __init timed_output_init(void)
+{
+       return create_timed_output_class();
+}
+
+static void __exit timed_output_exit(void)
+{
+       class_destroy(timed_output_class);
+}
+
+module_init(timed_output_init);
+module_exit(timed_output_exit);
+
+MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
+MODULE_DESCRIPTION("timed output class driver");
+MODULE_LICENSE("GPL");