USB: handle errors in power/level attribute
[linux-2.6] / drivers / video / output.c
1 /*
2  *  output.c - Display Output Switch driver
3  *
4  *  Copyright (C) 2006 Luming Yu <luming.yu@intel.com>
5  *
6  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or (at
11  *  your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful, but
14  *  WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License along
19  *  with this program; if not, write to the Free Software Foundation, Inc.,
20  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21  *
22  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23  */
24 #include <linux/module.h>
25 #include <linux/video_output.h>
26 #include <linux/err.h>
27 #include <linux/ctype.h>
28
29
30 MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction");
31 MODULE_LICENSE("GPL");
32 MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>");
33
34 static ssize_t video_output_show_state(struct class_device *dev,char *buf)
35 {
36         ssize_t ret_size = 0;
37         struct output_device *od = to_output_device(dev);
38         if (od->props)
39                 ret_size = sprintf(buf,"%.8x\n",od->props->get_status(od));
40         return ret_size;
41 }
42
43 static ssize_t video_output_store_state(struct class_device *dev,
44         const char *buf,size_t count)
45 {
46         char *endp;
47         struct output_device *od = to_output_device(dev);
48         int request_state = simple_strtoul(buf,&endp,0);
49         size_t size = endp - buf;
50
51         if (*endp && isspace(*endp))
52                 size++;
53         if (size != count)
54                 return -EINVAL;
55
56         if (od->props) {
57                 od->request_state = request_state;
58                 od->props->set_state(od);
59         }
60         return count;
61 }
62
63 static void video_output_class_release(struct class_device *dev)
64 {
65         struct output_device *od = to_output_device(dev);
66         kfree(od);
67 }
68
69 static struct class_device_attribute video_output_attributes[] = {
70         __ATTR(state, 0644, video_output_show_state, video_output_store_state),
71         __ATTR_NULL,
72 };
73
74 static struct class video_output_class = {
75         .name = "video_output",
76         .release = video_output_class_release,
77         .class_dev_attrs = video_output_attributes,
78 };
79
80 struct output_device *video_output_register(const char *name,
81         struct device *dev,
82         void *devdata,
83         struct output_properties *op)
84 {
85         struct output_device *new_dev;
86         int ret_code = 0;
87
88         new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL);
89         if (!new_dev) {
90                 ret_code = -ENOMEM;
91                 goto error_return;
92         }
93         new_dev->props = op;
94         new_dev->class_dev.class = &video_output_class;
95         new_dev->class_dev.dev = dev;
96         strlcpy(new_dev->class_dev.class_id,name,KOBJ_NAME_LEN);
97         class_set_devdata(&new_dev->class_dev,devdata);
98         ret_code = class_device_register(&new_dev->class_dev);
99         if (ret_code) {
100                 kfree(new_dev);
101                 goto error_return;
102         }
103         return new_dev;
104
105 error_return:
106         return ERR_PTR(ret_code);
107 }
108 EXPORT_SYMBOL(video_output_register);
109
110 void video_output_unregister(struct output_device *dev)
111 {
112         if (!dev)
113                 return;
114         class_device_unregister(&dev->class_dev);
115 }
116 EXPORT_SYMBOL(video_output_unregister);
117
118 static void __exit video_output_class_exit(void)
119 {
120         class_unregister(&video_output_class);
121 }
122
123 static int __init video_output_class_init(void)
124 {
125         return class_register(&video_output_class);
126 }
127
128 postcore_initcall(video_output_class_init);
129 module_exit(video_output_class_exit);