xref: /openbmc/linux/drivers/base/class.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1 /*
2  * class.c - basic device class management
3  *
4  * Copyright (c) 2002-3 Patrick Mochel
5  * Copyright (c) 2002-3 Open Source Development Labs
6  * Copyright (c) 2003-2004 Greg Kroah-Hartman
7  * Copyright (c) 2003-2004 IBM Corp.
8  *
9  * This file is released under the GPLv2
10  *
11  */
12 
13 #include <linux/config.h>
14 #include <linux/device.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/string.h>
18 #include <linux/kdev_t.h>
19 #include "base.h"
20 
21 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
22 #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj)
23 
24 static ssize_t
25 class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
26 {
27 	struct class_attribute * class_attr = to_class_attr(attr);
28 	struct class * dc = to_class(kobj);
29 	ssize_t ret = 0;
30 
31 	if (class_attr->show)
32 		ret = class_attr->show(dc, buf);
33 	return ret;
34 }
35 
36 static ssize_t
37 class_attr_store(struct kobject * kobj, struct attribute * attr,
38 		 const char * buf, size_t count)
39 {
40 	struct class_attribute * class_attr = to_class_attr(attr);
41 	struct class * dc = to_class(kobj);
42 	ssize_t ret = 0;
43 
44 	if (class_attr->store)
45 		ret = class_attr->store(dc, buf, count);
46 	return ret;
47 }
48 
49 static void class_release(struct kobject * kobj)
50 {
51 	struct class *class = to_class(kobj);
52 
53 	pr_debug("class '%s': release.\n", class->name);
54 
55 	if (class->class_release)
56 		class->class_release(class);
57 	else
58 		pr_debug("class '%s' does not have a release() function, "
59 			 "be careful\n", class->name);
60 }
61 
62 static struct sysfs_ops class_sysfs_ops = {
63 	.show	= class_attr_show,
64 	.store	= class_attr_store,
65 };
66 
67 static struct kobj_type ktype_class = {
68 	.sysfs_ops	= &class_sysfs_ops,
69 	.release	= class_release,
70 };
71 
72 /* Hotplug events for classes go to the class_obj subsys */
73 static decl_subsys(class, &ktype_class, NULL);
74 
75 
76 int class_create_file(struct class * cls, const struct class_attribute * attr)
77 {
78 	int error;
79 	if (cls) {
80 		error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr);
81 	} else
82 		error = -EINVAL;
83 	return error;
84 }
85 
86 void class_remove_file(struct class * cls, const struct class_attribute * attr)
87 {
88 	if (cls)
89 		sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr);
90 }
91 
92 struct class * class_get(struct class * cls)
93 {
94 	if (cls)
95 		return container_of(subsys_get(&cls->subsys), struct class, subsys);
96 	return NULL;
97 }
98 
99 void class_put(struct class * cls)
100 {
101 	subsys_put(&cls->subsys);
102 }
103 
104 
105 static int add_class_attrs(struct class * cls)
106 {
107 	int i;
108 	int error = 0;
109 
110 	if (cls->class_attrs) {
111 		for (i = 0; attr_name(cls->class_attrs[i]); i++) {
112 			error = class_create_file(cls,&cls->class_attrs[i]);
113 			if (error)
114 				goto Err;
115 		}
116 	}
117  Done:
118 	return error;
119  Err:
120 	while (--i >= 0)
121 		class_remove_file(cls,&cls->class_attrs[i]);
122 	goto Done;
123 }
124 
125 static void remove_class_attrs(struct class * cls)
126 {
127 	int i;
128 
129 	if (cls->class_attrs) {
130 		for (i = 0; attr_name(cls->class_attrs[i]); i++)
131 			class_remove_file(cls,&cls->class_attrs[i]);
132 	}
133 }
134 
135 int class_register(struct class * cls)
136 {
137 	int error;
138 
139 	pr_debug("device class '%s': registering\n", cls->name);
140 
141 	INIT_LIST_HEAD(&cls->children);
142 	INIT_LIST_HEAD(&cls->interfaces);
143 	init_MUTEX(&cls->sem);
144 	error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name);
145 	if (error)
146 		return error;
147 
148 	subsys_set_kset(cls, class_subsys);
149 
150 	error = subsystem_register(&cls->subsys);
151 	if (!error) {
152 		error = add_class_attrs(class_get(cls));
153 		class_put(cls);
154 	}
155 	return error;
156 }
157 
158 void class_unregister(struct class * cls)
159 {
160 	pr_debug("device class '%s': unregistering\n", cls->name);
161 	remove_class_attrs(cls);
162 	subsystem_unregister(&cls->subsys);
163 }
164 
165 
166 /* Class Device Stuff */
167 
168 int class_device_create_file(struct class_device * class_dev,
169 			     const struct class_device_attribute * attr)
170 {
171 	int error = -EINVAL;
172 	if (class_dev)
173 		error = sysfs_create_file(&class_dev->kobj, &attr->attr);
174 	return error;
175 }
176 
177 void class_device_remove_file(struct class_device * class_dev,
178 			      const struct class_device_attribute * attr)
179 {
180 	if (class_dev)
181 		sysfs_remove_file(&class_dev->kobj, &attr->attr);
182 }
183 
184 int class_device_create_bin_file(struct class_device *class_dev,
185 				 struct bin_attribute *attr)
186 {
187 	int error = -EINVAL;
188 	if (class_dev)
189 		error = sysfs_create_bin_file(&class_dev->kobj, attr);
190 	return error;
191 }
192 
193 void class_device_remove_bin_file(struct class_device *class_dev,
194 				  struct bin_attribute *attr)
195 {
196 	if (class_dev)
197 		sysfs_remove_bin_file(&class_dev->kobj, attr);
198 }
199 
200 static ssize_t
201 class_device_attr_show(struct kobject * kobj, struct attribute * attr,
202 		       char * buf)
203 {
204 	struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
205 	struct class_device * cd = to_class_dev(kobj);
206 	ssize_t ret = 0;
207 
208 	if (class_dev_attr->show)
209 		ret = class_dev_attr->show(cd, buf);
210 	return ret;
211 }
212 
213 static ssize_t
214 class_device_attr_store(struct kobject * kobj, struct attribute * attr,
215 			const char * buf, size_t count)
216 {
217 	struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
218 	struct class_device * cd = to_class_dev(kobj);
219 	ssize_t ret = 0;
220 
221 	if (class_dev_attr->store)
222 		ret = class_dev_attr->store(cd, buf, count);
223 	return ret;
224 }
225 
226 static struct sysfs_ops class_dev_sysfs_ops = {
227 	.show	= class_device_attr_show,
228 	.store	= class_device_attr_store,
229 };
230 
231 static void class_dev_release(struct kobject * kobj)
232 {
233 	struct class_device *cd = to_class_dev(kobj);
234 	struct class * cls = cd->class;
235 
236 	pr_debug("device class '%s': release.\n", cd->class_id);
237 
238 	if (cls->release)
239 		cls->release(cd);
240 	else {
241 		printk(KERN_ERR "Device class '%s' does not have a release() function, "
242 			"it is broken and must be fixed.\n",
243 			cd->class_id);
244 		WARN_ON(1);
245 	}
246 }
247 
248 static struct kobj_type ktype_class_device = {
249 	.sysfs_ops	= &class_dev_sysfs_ops,
250 	.release	= class_dev_release,
251 };
252 
253 static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
254 {
255 	struct kobj_type *ktype = get_ktype(kobj);
256 
257 	if (ktype == &ktype_class_device) {
258 		struct class_device *class_dev = to_class_dev(kobj);
259 		if (class_dev->class)
260 			return 1;
261 	}
262 	return 0;
263 }
264 
265 static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
266 {
267 	struct class_device *class_dev = to_class_dev(kobj);
268 
269 	return class_dev->class->name;
270 }
271 
272 static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
273 			 int num_envp, char *buffer, int buffer_size)
274 {
275 	struct class_device *class_dev = to_class_dev(kobj);
276 	int i = 0;
277 	int length = 0;
278 	int retval = 0;
279 
280 	pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
281 
282 	if (class_dev->dev) {
283 		/* add physical device, backing this device  */
284 		struct device *dev = class_dev->dev;
285 		char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
286 
287 		add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
288 				    &length, "PHYSDEVPATH=%s", path);
289 		kfree(path);
290 
291 		if (dev->bus)
292 			add_hotplug_env_var(envp, num_envp, &i,
293 					    buffer, buffer_size, &length,
294 					    "PHYSDEVBUS=%s", dev->bus->name);
295 
296 		if (dev->driver)
297 			add_hotplug_env_var(envp, num_envp, &i,
298 					    buffer, buffer_size, &length,
299 					    "PHYSDEVDRIVER=%s", dev->driver->name);
300 	}
301 
302 	if (MAJOR(class_dev->devt)) {
303 		add_hotplug_env_var(envp, num_envp, &i,
304 				    buffer, buffer_size, &length,
305 				    "MAJOR=%u", MAJOR(class_dev->devt));
306 
307 		add_hotplug_env_var(envp, num_envp, &i,
308 				    buffer, buffer_size, &length,
309 				    "MINOR=%u", MINOR(class_dev->devt));
310 	}
311 
312 	/* terminate, set to next free slot, shrink available space */
313 	envp[i] = NULL;
314 	envp = &envp[i];
315 	num_envp -= i;
316 	buffer = &buffer[length];
317 	buffer_size -= length;
318 
319 	if (class_dev->class->hotplug) {
320 		/* have the bus specific function add its stuff */
321 		retval = class_dev->class->hotplug (class_dev, envp, num_envp,
322 						    buffer, buffer_size);
323 			if (retval) {
324 			pr_debug ("%s - hotplug() returned %d\n",
325 				  __FUNCTION__, retval);
326 		}
327 	}
328 
329 	return retval;
330 }
331 
332 static struct kset_hotplug_ops class_hotplug_ops = {
333 	.filter =	class_hotplug_filter,
334 	.name =		class_hotplug_name,
335 	.hotplug =	class_hotplug,
336 };
337 
338 static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
339 
340 
341 static int class_device_add_attrs(struct class_device * cd)
342 {
343 	int i;
344 	int error = 0;
345 	struct class * cls = cd->class;
346 
347 	if (cls->class_dev_attrs) {
348 		for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
349 			error = class_device_create_file(cd,
350 							 &cls->class_dev_attrs[i]);
351 			if (error)
352 				goto Err;
353 		}
354 	}
355  Done:
356 	return error;
357  Err:
358 	while (--i >= 0)
359 		class_device_remove_file(cd,&cls->class_dev_attrs[i]);
360 	goto Done;
361 }
362 
363 static void class_device_remove_attrs(struct class_device * cd)
364 {
365 	int i;
366 	struct class * cls = cd->class;
367 
368 	if (cls->class_dev_attrs) {
369 		for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
370 			class_device_remove_file(cd,&cls->class_dev_attrs[i]);
371 	}
372 }
373 
374 static ssize_t show_dev(struct class_device *class_dev, char *buf)
375 {
376 	return print_dev_t(buf, class_dev->devt);
377 }
378 static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
379 
380 void class_device_initialize(struct class_device *class_dev)
381 {
382 	kobj_set_kset_s(class_dev, class_obj_subsys);
383 	kobject_init(&class_dev->kobj);
384 	INIT_LIST_HEAD(&class_dev->node);
385 }
386 
387 int class_device_add(struct class_device *class_dev)
388 {
389 	struct class * parent = NULL;
390 	struct class_interface * class_intf;
391 	int error;
392 
393 	class_dev = class_device_get(class_dev);
394 	if (!class_dev)
395 		return -EINVAL;
396 
397 	if (!strlen(class_dev->class_id)) {
398 		error = -EINVAL;
399 		goto register_done;
400 	}
401 
402 	parent = class_get(class_dev->class);
403 
404 	pr_debug("CLASS: registering class device: ID = '%s'\n",
405 		 class_dev->class_id);
406 
407 	/* first, register with generic layer. */
408 	kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
409 	if (parent)
410 		class_dev->kobj.parent = &parent->subsys.kset.kobj;
411 
412 	if ((error = kobject_add(&class_dev->kobj)))
413 		goto register_done;
414 
415 	/* now take care of our own registration */
416 	if (parent) {
417 		down(&parent->sem);
418 		list_add_tail(&class_dev->node, &parent->children);
419 		list_for_each_entry(class_intf, &parent->interfaces, node)
420 			if (class_intf->add)
421 				class_intf->add(class_dev);
422 		up(&parent->sem);
423 	}
424 
425 	if (MAJOR(class_dev->devt))
426 		class_device_create_file(class_dev, &class_device_attr_dev);
427 
428 	class_device_add_attrs(class_dev);
429 	if (class_dev->dev)
430 		sysfs_create_link(&class_dev->kobj,
431 				  &class_dev->dev->kobj, "device");
432 
433  register_done:
434 	if (error && parent)
435 		class_put(parent);
436 	class_device_put(class_dev);
437 	return error;
438 }
439 
440 int class_device_register(struct class_device *class_dev)
441 {
442 	class_device_initialize(class_dev);
443 	return class_device_add(class_dev);
444 }
445 
446 void class_device_del(struct class_device *class_dev)
447 {
448 	struct class * parent = class_dev->class;
449 	struct class_interface * class_intf;
450 
451 	if (parent) {
452 		down(&parent->sem);
453 		list_del_init(&class_dev->node);
454 		list_for_each_entry(class_intf, &parent->interfaces, node)
455 			if (class_intf->remove)
456 				class_intf->remove(class_dev);
457 		up(&parent->sem);
458 	}
459 
460 	if (class_dev->dev)
461 		sysfs_remove_link(&class_dev->kobj, "device");
462 	class_device_remove_attrs(class_dev);
463 
464 	kobject_del(&class_dev->kobj);
465 
466 	if (parent)
467 		class_put(parent);
468 }
469 
470 void class_device_unregister(struct class_device *class_dev)
471 {
472 	pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
473 		 class_dev->class_id);
474 	class_device_del(class_dev);
475 	class_device_put(class_dev);
476 }
477 
478 int class_device_rename(struct class_device *class_dev, char *new_name)
479 {
480 	int error = 0;
481 
482 	class_dev = class_device_get(class_dev);
483 	if (!class_dev)
484 		return -EINVAL;
485 
486 	pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
487 		 new_name);
488 
489 	strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
490 
491 	error = kobject_rename(&class_dev->kobj, new_name);
492 
493 	class_device_put(class_dev);
494 
495 	return error;
496 }
497 
498 struct class_device * class_device_get(struct class_device *class_dev)
499 {
500 	if (class_dev)
501 		return to_class_dev(kobject_get(&class_dev->kobj));
502 	return NULL;
503 }
504 
505 void class_device_put(struct class_device *class_dev)
506 {
507 	kobject_put(&class_dev->kobj);
508 }
509 
510 
511 int class_interface_register(struct class_interface *class_intf)
512 {
513 	struct class *parent;
514 	struct class_device *class_dev;
515 
516 	if (!class_intf || !class_intf->class)
517 		return -ENODEV;
518 
519 	parent = class_get(class_intf->class);
520 	if (!parent)
521 		return -EINVAL;
522 
523 	down(&parent->sem);
524 	list_add_tail(&class_intf->node, &parent->interfaces);
525 	if (class_intf->add) {
526 		list_for_each_entry(class_dev, &parent->children, node)
527 			class_intf->add(class_dev);
528 	}
529 	up(&parent->sem);
530 
531 	return 0;
532 }
533 
534 void class_interface_unregister(struct class_interface *class_intf)
535 {
536 	struct class * parent = class_intf->class;
537 	struct class_device *class_dev;
538 
539 	if (!parent)
540 		return;
541 
542 	down(&parent->sem);
543 	list_del_init(&class_intf->node);
544 	if (class_intf->remove) {
545 		list_for_each_entry(class_dev, &parent->children, node)
546 			class_intf->remove(class_dev);
547 	}
548 	up(&parent->sem);
549 
550 	class_put(parent);
551 }
552 
553 
554 
555 int __init classes_init(void)
556 {
557 	int retval;
558 
559 	retval = subsystem_register(&class_subsys);
560 	if (retval)
561 		return retval;
562 
563 	/* ick, this is ugly, the things we go through to keep from showing up
564 	 * in sysfs... */
565 	subsystem_init(&class_obj_subsys);
566 	if (!class_obj_subsys.kset.subsys)
567 			class_obj_subsys.kset.subsys = &class_obj_subsys;
568 	return 0;
569 }
570 
571 EXPORT_SYMBOL_GPL(class_create_file);
572 EXPORT_SYMBOL_GPL(class_remove_file);
573 EXPORT_SYMBOL_GPL(class_register);
574 EXPORT_SYMBOL_GPL(class_unregister);
575 EXPORT_SYMBOL_GPL(class_get);
576 EXPORT_SYMBOL_GPL(class_put);
577 
578 EXPORT_SYMBOL_GPL(class_device_register);
579 EXPORT_SYMBOL_GPL(class_device_unregister);
580 EXPORT_SYMBOL_GPL(class_device_initialize);
581 EXPORT_SYMBOL_GPL(class_device_add);
582 EXPORT_SYMBOL_GPL(class_device_del);
583 EXPORT_SYMBOL_GPL(class_device_get);
584 EXPORT_SYMBOL_GPL(class_device_put);
585 EXPORT_SYMBOL_GPL(class_device_create_file);
586 EXPORT_SYMBOL_GPL(class_device_remove_file);
587 EXPORT_SYMBOL_GPL(class_device_create_bin_file);
588 EXPORT_SYMBOL_GPL(class_device_remove_bin_file);
589 
590 EXPORT_SYMBOL_GPL(class_interface_register);
591 EXPORT_SYMBOL_GPL(class_interface_unregister);
592