1 /* drivers/misc/timed_output.c
3 * Copyright (C) 2009 Google, Inc.
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #define pr_fmt(fmt) "timed_output: " fmt
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/device.h>
23 #include <linux/err.h>
25 #include "timed_output.h"
27 static struct class *timed_output_class;
28 static atomic_t device_count;
30 static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
33 struct timed_output_dev *tdev = dev_get_drvdata(dev);
34 int remaining = tdev->get_time(tdev);
36 return sprintf(buf, "%d\n", remaining);
39 static ssize_t enable_store(
40 struct device *dev, struct device_attribute *attr,
41 const char *buf, size_t size)
43 struct timed_output_dev *tdev = dev_get_drvdata(dev);
46 if (sscanf(buf, "%d", &value) != 1)
49 tdev->enable(tdev, value);
54 static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
56 static int create_timed_output_class(void)
58 if (!timed_output_class) {
59 timed_output_class = class_create(THIS_MODULE, "timed_output");
60 if (IS_ERR(timed_output_class))
61 return PTR_ERR(timed_output_class);
62 atomic_set(&device_count, 0);
68 int timed_output_dev_register(struct timed_output_dev *tdev)
72 if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time)
75 ret = create_timed_output_class();
79 tdev->index = atomic_inc_return(&device_count);
80 tdev->dev = device_create(timed_output_class, NULL,
81 MKDEV(0, tdev->index), NULL, tdev->name);
82 if (IS_ERR(tdev->dev))
83 return PTR_ERR(tdev->dev);
85 ret = device_create_file(tdev->dev, &dev_attr_enable);
89 dev_set_drvdata(tdev->dev, tdev);
94 device_destroy(timed_output_class, MKDEV(0, tdev->index));
95 pr_err("failed to register driver %s\n",
100 EXPORT_SYMBOL_GPL(timed_output_dev_register);
102 void timed_output_dev_unregister(struct timed_output_dev *tdev)
104 tdev->enable(tdev, 0);
105 device_remove_file(tdev->dev, &dev_attr_enable);
106 device_destroy(timed_output_class, MKDEV(0, tdev->index));
107 dev_set_drvdata(tdev->dev, NULL);
109 EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
111 static int __init timed_output_init(void)
113 return create_timed_output_class();
116 static void __exit timed_output_exit(void)
118 class_destroy(timed_output_class);
121 module_init(timed_output_init);
122 module_exit(timed_output_exit);
125 MODULE_DESCRIPTION("timed output class driver");
126 MODULE_LICENSE("GPL");