1 /* drivers/misc/timed_output.c
3 * Copyright (C) 2009 Google, Inc.
4 * Author: Mike Lockwood <lockwood@android.com>
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 #include <linux/module.h>
18 #include <linux/types.h>
19 #include <linux/device.h>
21 #include <linux/err.h>
23 #include "timed_output.h"
25 static struct class *timed_output_class
;
26 static atomic_t device_count
;
28 static ssize_t
enable_show(struct device
*dev
, struct device_attribute
*attr
,
31 struct timed_output_dev
*tdev
= dev_get_drvdata(dev
);
32 int remaining
= tdev
->get_time(tdev
);
34 return sprintf(buf
, "%d\n", remaining
);
37 static ssize_t
enable_store(
38 struct device
*dev
, struct device_attribute
*attr
,
39 const char *buf
, size_t size
)
41 struct timed_output_dev
*tdev
= dev_get_drvdata(dev
);
44 if (sscanf(buf
, "%d", &value
) != 1)
47 tdev
->enable(tdev
, value
);
52 static DEVICE_ATTR(enable
, S_IRUGO
| S_IWUSR
, enable_show
, enable_store
);
54 static int create_timed_output_class(void)
56 if (!timed_output_class
) {
57 timed_output_class
= class_create(THIS_MODULE
, "timed_output");
58 if (IS_ERR(timed_output_class
))
59 return PTR_ERR(timed_output_class
);
60 atomic_set(&device_count
, 0);
66 int timed_output_dev_register(struct timed_output_dev
*tdev
)
70 if (!tdev
|| !tdev
->name
|| !tdev
->enable
|| !tdev
->get_time
)
73 ret
= create_timed_output_class();
77 tdev
->index
= atomic_inc_return(&device_count
);
78 tdev
->dev
= device_create(timed_output_class
, NULL
,
79 MKDEV(0, tdev
->index
), NULL
, tdev
->name
);
80 if (IS_ERR(tdev
->dev
))
81 return PTR_ERR(tdev
->dev
);
83 ret
= device_create_file(tdev
->dev
, &dev_attr_enable
);
87 dev_set_drvdata(tdev
->dev
, tdev
);
92 device_destroy(timed_output_class
, MKDEV(0, tdev
->index
));
93 printk(KERN_ERR
"timed_output: Failed to register driver %s\n",
98 EXPORT_SYMBOL_GPL(timed_output_dev_register
);
100 void timed_output_dev_unregister(struct timed_output_dev
*tdev
)
102 device_remove_file(tdev
->dev
, &dev_attr_enable
);
103 device_destroy(timed_output_class
, MKDEV(0, tdev
->index
));
104 dev_set_drvdata(tdev
->dev
, NULL
);
106 EXPORT_SYMBOL_GPL(timed_output_dev_unregister
);
108 static int __init
timed_output_init(void)
110 return create_timed_output_class();
113 static void __exit
timed_output_exit(void)
115 class_destroy(timed_output_class
);
118 module_init(timed_output_init
);
119 module_exit(timed_output_exit
);
121 MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
122 MODULE_DESCRIPTION("timed output class driver");
123 MODULE_LICENSE("GPL");