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/device.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/string.h>
17#include <linux/kdev_t.h>
18#include <linux/err.h>
19#include <linux/slab.h>
20#include "base.h"
21
22#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
23#define to_class(obj) container_of(obj, struct class, subsys.kobj)
24
25static ssize_t
26class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
27{
28	struct class_attribute * class_attr = to_class_attr(attr);
29	struct class * dc = to_class(kobj);
30	ssize_t ret = -EIO;
31
32	if (class_attr->show)
33		ret = class_attr->show(dc, buf);
34	return ret;
35}
36
37static ssize_t
38class_attr_store(struct kobject * kobj, struct attribute * attr,
39		 const char * buf, size_t count)
40{
41	struct class_attribute * class_attr = to_class_attr(attr);
42	struct class * dc = to_class(kobj);
43	ssize_t ret = -EIO;
44
45	if (class_attr->store)
46		ret = class_attr->store(dc, buf, count);
47	return ret;
48}
49
50static void class_release(struct kobject * kobj)
51{
52	struct class *class = to_class(kobj);
53
54	pr_debug("class '%s': release.\n", class->name);
55
56	if (class->class_release)
57		class->class_release(class);
58	else
59		pr_debug("class '%s' does not have a release() function, "
60			 "be careful\n", class->name);
61}
62
63static struct sysfs_ops class_sysfs_ops = {
64	.show	= class_attr_show,
65	.store	= class_attr_store,
66};
67
68static struct kobj_type ktype_class = {
69	.sysfs_ops	= &class_sysfs_ops,
70	.release	= class_release,
71};
72
73/* Hotplug events for classes go to the class_obj subsys */
74static decl_subsys(class, &ktype_class, NULL);
75
76
77int class_create_file(struct class * cls, const struct class_attribute * attr)
78{
79	int error;
80	if (cls) {
81		error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
82	} else
83		error = -EINVAL;
84	return error;
85}
86
87void class_remove_file(struct class * cls, const struct class_attribute * attr)
88{
89	if (cls)
90		sysfs_remove_file(&cls->subsys.kobj, &attr->attr);
91}
92
93static struct class *class_get(struct class *cls)
94{
95	if (cls)
96		return container_of(subsys_get(&cls->subsys), struct class, subsys);
97	return NULL;
98}
99
100static void class_put(struct class * cls)
101{
102	if (cls)
103		subsys_put(&cls->subsys);
104}
105
106
107static int add_class_attrs(struct class * cls)
108{
109	int i;
110	int error = 0;
111
112	if (cls->class_attrs) {
113		for (i = 0; attr_name(cls->class_attrs[i]); i++) {
114			error = class_create_file(cls,&cls->class_attrs[i]);
115			if (error)
116				goto Err;
117		}
118	}
119 Done:
120	return error;
121 Err:
122	while (--i >= 0)
123		class_remove_file(cls,&cls->class_attrs[i]);
124	goto Done;
125}
126
127static void remove_class_attrs(struct class * cls)
128{
129	int i;
130
131	if (cls->class_attrs) {
132		for (i = 0; attr_name(cls->class_attrs[i]); i++)
133			class_remove_file(cls,&cls->class_attrs[i]);
134	}
135}
136
137int class_register(struct class * cls)
138{
139	int error;
140
141	pr_debug("device class '%s': registering\n", cls->name);
142
143	INIT_LIST_HEAD(&cls->children);
144	INIT_LIST_HEAD(&cls->devices);
145	INIT_LIST_HEAD(&cls->interfaces);
146	kset_init(&cls->class_dirs);
147	init_MUTEX(&cls->sem);
148	error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);
149	if (error)
150		return error;
151
152	subsys_set_kset(cls, class_subsys);
153
154	error = subsystem_register(&cls->subsys);
155	if (!error) {
156		error = add_class_attrs(class_get(cls));
157		class_put(cls);
158	}
159	return error;
160}
161
162void class_unregister(struct class * cls)
163{
164	pr_debug("device class '%s': unregistering\n", cls->name);
165	remove_class_attrs(cls);
166	subsystem_unregister(&cls->subsys);
167}
168
169static void class_create_release(struct class *cls)
170{
171	pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
172	kfree(cls);
173}
174
175static void class_device_create_release(struct class_device *class_dev)
176{
177	pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
178	kfree(class_dev);
179}
180
181/* needed to allow these devices to have parent class devices */
182static int class_device_create_uevent(struct class_device *class_dev,
183				       char **envp, int num_envp,
184				       char *buffer, int buffer_size)
185{
186	pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
187	return 0;
188}
189
190/**
191 * class_create - create a struct class structure
192 * @owner: pointer to the module that is to "own" this struct class
193 * @name: pointer to a string for the name of this class.
194 *
195 * This is used to create a struct class pointer that can then be used
196 * in calls to class_device_create().
197 *
198 * Note, the pointer created here is to be destroyed when finished by
199 * making a call to class_destroy().
200 */
201struct class *class_create(struct module *owner, const char *name)
202{
203	struct class *cls;
204	int retval;
205
206	cls = kzalloc(sizeof(*cls), GFP_KERNEL);
207	if (!cls) {
208		retval = -ENOMEM;
209		goto error;
210	}
211
212	cls->name = name;
213	cls->owner = owner;
214	cls->class_release = class_create_release;
215	cls->release = class_device_create_release;
216
217	retval = class_register(cls);
218	if (retval)
219		goto error;
220
221	return cls;
222
223error:
224	kfree(cls);
225	return ERR_PTR(retval);
226}
227
228/**
229 * class_destroy - destroys a struct class structure
230 * @cls: pointer to the struct class that is to be destroyed
231 *
232 * Note, the pointer to be destroyed must have been created with a call
233 * to class_create().
234 */
235void class_destroy(struct class *cls)
236{
237	if ((cls == NULL) || (IS_ERR(cls)))
238		return;
239
240	class_unregister(cls);
241}
242
243/* Class Device Stuff */
244
245int class_device_create_file(struct class_device * class_dev,
246			     const struct class_device_attribute * attr)
247{
248	int error = -EINVAL;
249	if (class_dev)
250		error = sysfs_create_file(&class_dev->kobj, &attr->attr);
251	return error;
252}
253
254void class_device_remove_file(struct class_device * class_dev,
255			      const struct class_device_attribute * attr)
256{
257	if (class_dev)
258		sysfs_remove_file(&class_dev->kobj, &attr->attr);
259}
260
261int class_device_create_bin_file(struct class_device *class_dev,
262				 struct bin_attribute *attr)
263{
264	int error = -EINVAL;
265	if (class_dev)
266		error = sysfs_create_bin_file(&class_dev->kobj, attr);
267	return error;
268}
269
270void class_device_remove_bin_file(struct class_device *class_dev,
271				  struct bin_attribute *attr)
272{
273	if (class_dev)
274		sysfs_remove_bin_file(&class_dev->kobj, attr);
275}
276
277static ssize_t
278class_device_attr_show(struct kobject * kobj, struct attribute * attr,
279		       char * buf)
280{
281	struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
282	struct class_device * cd = to_class_dev(kobj);
283	ssize_t ret = 0;
284
285	if (class_dev_attr->show)
286		ret = class_dev_attr->show(cd, buf);
287	return ret;
288}
289
290static ssize_t
291class_device_attr_store(struct kobject * kobj, struct attribute * attr,
292			const char * buf, size_t count)
293{
294	struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
295	struct class_device * cd = to_class_dev(kobj);
296	ssize_t ret = 0;
297
298	if (class_dev_attr->store)
299		ret = class_dev_attr->store(cd, buf, count);
300	return ret;
301}
302
303static struct sysfs_ops class_dev_sysfs_ops = {
304	.show	= class_device_attr_show,
305	.store	= class_device_attr_store,
306};
307
308static void class_dev_release(struct kobject * kobj)
309{
310	struct class_device *cd = to_class_dev(kobj);
311	struct class * cls = cd->class;
312
313	pr_debug("device class '%s': release.\n", cd->class_id);
314
315	kfree(cd->devt_attr);
316	cd->devt_attr = NULL;
317
318	if (cd->release)
319		cd->release(cd);
320	else if (cls->release)
321		cls->release(cd);
322	else {
323		printk(KERN_ERR "Class Device '%s' does not have a release() function, "
324			"it is broken and must be fixed.\n",
325			cd->class_id);
326		WARN_ON(1);
327	}
328}
329
330static struct kobj_type ktype_class_device = {
331	.sysfs_ops	= &class_dev_sysfs_ops,
332	.release	= class_dev_release,
333};
334
335static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
336{
337	struct kobj_type *ktype = get_ktype(kobj);
338
339	if (ktype == &ktype_class_device) {
340		struct class_device *class_dev = to_class_dev(kobj);
341		if (class_dev->class)
342			return 1;
343	}
344	return 0;
345}
346
347static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
348{
349	struct class_device *class_dev = to_class_dev(kobj);
350
351	return class_dev->class->name;
352}
353
354#ifdef CONFIG_SYSFS_DEPRECATED
355char *make_class_name(const char *name, struct kobject *kobj)
356{
357	char *class_name;
358	int size;
359
360	size = strlen(name) + strlen(kobject_name(kobj)) + 2;
361
362	class_name = kmalloc(size, GFP_KERNEL);
363	if (!class_name)
364		return NULL;
365
366	strcpy(class_name, name);
367	strcat(class_name, ":");
368	strcat(class_name, kobject_name(kobj));
369	return class_name;
370}
371
372static int make_deprecated_class_device_links(struct class_device *class_dev)
373{
374	char *class_name;
375	int error;
376
377	if (!class_dev->dev)
378		return 0;
379
380	class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
381	if (class_name)
382		error = sysfs_create_link(&class_dev->dev->kobj,
383					  &class_dev->kobj, class_name);
384	else
385		error = -ENOMEM;
386	kfree(class_name);
387	return error;
388}
389
390static void remove_deprecated_class_device_links(struct class_device *class_dev)
391{
392	char *class_name;
393
394	if (!class_dev->dev)
395		return;
396
397	class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
398	if (class_name)
399		sysfs_remove_link(&class_dev->dev->kobj, class_name);
400	kfree(class_name);
401}
402#else
403static inline int make_deprecated_class_device_links(struct class_device *cd)
404{ return 0; }
405static void remove_deprecated_class_device_links(struct class_device *cd)
406{ }
407#endif
408
409static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
410			 int num_envp, char *buffer, int buffer_size)
411{
412	struct class_device *class_dev = to_class_dev(kobj);
413	struct device *dev = class_dev->dev;
414	int i = 0;
415	int length = 0;
416	int retval = 0;
417
418	pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
419
420	if (MAJOR(class_dev->devt)) {
421		add_uevent_var(envp, num_envp, &i,
422			       buffer, buffer_size, &length,
423			       "MAJOR=%u", MAJOR(class_dev->devt));
424
425		add_uevent_var(envp, num_envp, &i,
426			       buffer, buffer_size, &length,
427			       "MINOR=%u", MINOR(class_dev->devt));
428	}
429
430	if (dev) {
431		const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
432		if (path) {
433			add_uevent_var(envp, num_envp, &i,
434				       buffer, buffer_size, &length,
435				       "PHYSDEVPATH=%s", path);
436			kfree(path);
437		}
438
439		if (dev->bus)
440			add_uevent_var(envp, num_envp, &i,
441				       buffer, buffer_size, &length,
442				       "PHYSDEVBUS=%s", dev->bus->name);
443
444		if (dev->driver)
445			add_uevent_var(envp, num_envp, &i,
446				       buffer, buffer_size, &length,
447				       "PHYSDEVDRIVER=%s", dev->driver->name);
448	}
449
450	/* terminate, set to next free slot, shrink available space */
451	envp[i] = NULL;
452	envp = &envp[i];
453	num_envp -= i;
454	buffer = &buffer[length];
455	buffer_size -= length;
456
457	if (class_dev->uevent) {
458		/* have the class device specific function add its stuff */
459		retval = class_dev->uevent(class_dev, envp, num_envp,
460					    buffer, buffer_size);
461		if (retval)
462			pr_debug("class_dev->uevent() returned %d\n", retval);
463	} else if (class_dev->class->uevent) {
464		/* have the class specific function add its stuff */
465		retval = class_dev->class->uevent(class_dev, envp, num_envp,
466						   buffer, buffer_size);
467		if (retval)
468			pr_debug("class->uevent() returned %d\n", retval);
469	}
470
471	return retval;
472}
473
474static struct kset_uevent_ops class_uevent_ops = {
475	.filter =	class_uevent_filter,
476	.name =		class_uevent_name,
477	.uevent =	class_uevent,
478};
479
480static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);
481
482
483static int class_device_add_attrs(struct class_device * cd)
484{
485	int i;
486	int error = 0;
487	struct class * cls = cd->class;
488
489	if (cls->class_dev_attrs) {
490		for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
491			error = class_device_create_file(cd,
492							 &cls->class_dev_attrs[i]);
493			if (error)
494				goto Err;
495		}
496	}
497 Done:
498	return error;
499 Err:
500	while (--i >= 0)
501		class_device_remove_file(cd,&cls->class_dev_attrs[i]);
502	goto Done;
503}
504
505static void class_device_remove_attrs(struct class_device * cd)
506{
507	int i;
508	struct class * cls = cd->class;
509
510	if (cls->class_dev_attrs) {
511		for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
512			class_device_remove_file(cd,&cls->class_dev_attrs[i]);
513	}
514}
515
516static int class_device_add_groups(struct class_device * cd)
517{
518	int i;
519	int error = 0;
520
521	if (cd->groups) {
522		for (i = 0; cd->groups[i]; i++) {
523			error = sysfs_create_group(&cd->kobj, cd->groups[i]);
524			if (error) {
525				while (--i >= 0)
526					sysfs_remove_group(&cd->kobj, cd->groups[i]);
527				goto out;
528			}
529		}
530	}
531out:
532	return error;
533}
534
535static void class_device_remove_groups(struct class_device * cd)
536{
537	int i;
538	if (cd->groups) {
539		for (i = 0; cd->groups[i]; i++) {
540			sysfs_remove_group(&cd->kobj, cd->groups[i]);
541		}
542	}
543}
544
545static ssize_t show_dev(struct class_device *class_dev, char *buf)
546{
547	return print_dev_t(buf, class_dev->devt);
548}
549
550static ssize_t store_uevent(struct class_device *class_dev,
551			    const char *buf, size_t count)
552{
553	kobject_uevent(&class_dev->kobj, KOBJ_ADD);
554	return count;
555}
556
557void class_device_initialize(struct class_device *class_dev)
558{
559	kobj_set_kset_s(class_dev, class_obj_subsys);
560	kobject_init(&class_dev->kobj);
561	INIT_LIST_HEAD(&class_dev->node);
562}
563
564int class_device_add(struct class_device *class_dev)
565{
566	struct class *parent_class = NULL;
567	struct class_device *parent_class_dev = NULL;
568	struct class_interface *class_intf;
569	int error = -EINVAL;
570
571	class_dev = class_device_get(class_dev);
572	if (!class_dev)
573		return -EINVAL;
574
575	if (!strlen(class_dev->class_id))
576		goto out1;
577
578	parent_class = class_get(class_dev->class);
579	if (!parent_class)
580		goto out1;
581
582	parent_class_dev = class_device_get(class_dev->parent);
583
584	pr_debug("CLASS: registering class device: ID = '%s'\n",
585		 class_dev->class_id);
586
587	/* first, register with generic layer. */
588	error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
589	if (error)
590		goto out2;
591
592	if (parent_class_dev)
593		class_dev->kobj.parent = &parent_class_dev->kobj;
594	else
595		class_dev->kobj.parent = &parent_class->subsys.kobj;
596
597	error = kobject_add(&class_dev->kobj);
598	if (error)
599		goto out2;
600
601	/* add the needed attributes to this device */
602	error = sysfs_create_link(&class_dev->kobj,
603				  &parent_class->subsys.kobj, "subsystem");
604	if (error)
605		goto out3;
606	class_dev->uevent_attr.attr.name = "uevent";
607	class_dev->uevent_attr.attr.mode = S_IWUSR;
608	class_dev->uevent_attr.attr.owner = parent_class->owner;
609	class_dev->uevent_attr.store = store_uevent;
610	error = class_device_create_file(class_dev, &class_dev->uevent_attr);
611	if (error)
612		goto out3;
613
614	if (MAJOR(class_dev->devt)) {
615		struct class_device_attribute *attr;
616		attr = kzalloc(sizeof(*attr), GFP_KERNEL);
617		if (!attr) {
618			error = -ENOMEM;
619			goto out4;
620		}
621		attr->attr.name = "dev";
622		attr->attr.mode = S_IRUGO;
623		attr->attr.owner = parent_class->owner;
624		attr->show = show_dev;
625		error = class_device_create_file(class_dev, attr);
626		if (error) {
627			kfree(attr);
628			goto out4;
629		}
630
631		class_dev->devt_attr = attr;
632	}
633
634	error = class_device_add_attrs(class_dev);
635	if (error)
636		goto out5;
637
638	if (class_dev->dev) {
639		error = sysfs_create_link(&class_dev->kobj,
640					  &class_dev->dev->kobj, "device");
641		if (error)
642			goto out6;
643	}
644
645	error = class_device_add_groups(class_dev);
646	if (error)
647		goto out7;
648
649	error = make_deprecated_class_device_links(class_dev);
650	if (error)
651		goto out8;
652
653	kobject_uevent(&class_dev->kobj, KOBJ_ADD);
654
655	/* notify any interfaces this device is now here */
656	down(&parent_class->sem);
657	list_add_tail(&class_dev->node, &parent_class->children);
658	list_for_each_entry(class_intf, &parent_class->interfaces, node) {
659		if (class_intf->add)
660			class_intf->add(class_dev, class_intf);
661	}
662	up(&parent_class->sem);
663
664	goto out1;
665
666 out8:
667	class_device_remove_groups(class_dev);
668 out7:
669	if (class_dev->dev)
670		sysfs_remove_link(&class_dev->kobj, "device");
671 out6:
672	class_device_remove_attrs(class_dev);
673 out5:
674	if (class_dev->devt_attr)
675		class_device_remove_file(class_dev, class_dev->devt_attr);
676 out4:
677	class_device_remove_file(class_dev, &class_dev->uevent_attr);
678 out3:
679	kobject_del(&class_dev->kobj);
680 out2:
681	if(parent_class_dev)
682		class_device_put(parent_class_dev);
683	class_put(parent_class);
684 out1:
685	class_device_put(class_dev);
686	return error;
687}
688
689int class_device_register(struct class_device *class_dev)
690{
691	class_device_initialize(class_dev);
692	return class_device_add(class_dev);
693}
694
695/**
696 * class_device_create - creates a class device and registers it with sysfs
697 * @cls: pointer to the struct class that this device should be registered to.
698 * @parent: pointer to the parent struct class_device of this new device, if any.
699 * @devt: the dev_t for the char device to be added.
700 * @device: a pointer to a struct device that is assiociated with this class device.
701 * @fmt: string for the class device's name
702 *
703 * This function can be used by char device classes.  A struct
704 * class_device will be created in sysfs, registered to the specified
705 * class.
706 * A "dev" file will be created, showing the dev_t for the device, if
707 * the dev_t is not 0,0.
708 * If a pointer to a parent struct class_device is passed in, the newly
709 * created struct class_device will be a child of that device in sysfs.
710 * The pointer to the struct class_device will be returned from the
711 * call.  Any further sysfs files that might be required can be created
712 * using this pointer.
713 *
714 * Note: the struct class passed to this function must have previously
715 * been created with a call to class_create().
716 */
717struct class_device *class_device_create(struct class *cls,
718					 struct class_device *parent,
719					 dev_t devt,
720					 struct device *device,
721					 const char *fmt, ...)
722{
723	va_list args;
724	struct class_device *class_dev = NULL;
725	int retval = -ENODEV;
726
727	if (cls == NULL || IS_ERR(cls))
728		goto error;
729
730	class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
731	if (!class_dev) {
732		retval = -ENOMEM;
733		goto error;
734	}
735
736	class_dev->devt = devt;
737	class_dev->dev = device;
738	class_dev->class = cls;
739	class_dev->parent = parent;
740	class_dev->release = class_device_create_release;
741	class_dev->uevent = class_device_create_uevent;
742
743	va_start(args, fmt);
744	vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
745	va_end(args);
746	retval = class_device_register(class_dev);
747	if (retval)
748		goto error;
749
750	return class_dev;
751
752error:
753	kfree(class_dev);
754	return ERR_PTR(retval);
755}
756
757void class_device_del(struct class_device *class_dev)
758{
759	struct class *parent_class = class_dev->class;
760	struct class_device *parent_device = class_dev->parent;
761	struct class_interface *class_intf;
762
763	if (parent_class) {
764		down(&parent_class->sem);
765		list_del_init(&class_dev->node);
766		list_for_each_entry(class_intf, &parent_class->interfaces, node)
767			if (class_intf->remove)
768				class_intf->remove(class_dev, class_intf);
769		up(&parent_class->sem);
770	}
771
772	if (class_dev->dev) {
773		remove_deprecated_class_device_links(class_dev);
774		sysfs_remove_link(&class_dev->kobj, "device");
775	}
776	sysfs_remove_link(&class_dev->kobj, "subsystem");
777	class_device_remove_file(class_dev, &class_dev->uevent_attr);
778	if (class_dev->devt_attr)
779		class_device_remove_file(class_dev, class_dev->devt_attr);
780	class_device_remove_attrs(class_dev);
781	class_device_remove_groups(class_dev);
782
783	kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
784	kobject_del(&class_dev->kobj);
785
786	class_device_put(parent_device);
787	class_put(parent_class);
788}
789
790void class_device_unregister(struct class_device *class_dev)
791{
792	pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
793		 class_dev->class_id);
794	class_device_del(class_dev);
795	class_device_put(class_dev);
796}
797
798/**
799 * class_device_destroy - removes a class device that was created with class_device_create()
800 * @cls: the pointer to the struct class that this device was registered * with.
801 * @devt: the dev_t of the device that was previously registered.
802 *
803 * This call unregisters and cleans up a class device that was created with a
804 * call to class_device_create()
805 */
806void class_device_destroy(struct class *cls, dev_t devt)
807{
808	struct class_device *class_dev = NULL;
809	struct class_device *class_dev_tmp;
810
811	down(&cls->sem);
812	list_for_each_entry(class_dev_tmp, &cls->children, node) {
813		if (class_dev_tmp->devt == devt) {
814			class_dev = class_dev_tmp;
815			break;
816		}
817	}
818	up(&cls->sem);
819
820	if (class_dev)
821		class_device_unregister(class_dev);
822}
823
824struct class_device * class_device_get(struct class_device *class_dev)
825{
826	if (class_dev)
827		return to_class_dev(kobject_get(&class_dev->kobj));
828	return NULL;
829}
830
831void class_device_put(struct class_device *class_dev)
832{
833	if (class_dev)
834		kobject_put(&class_dev->kobj);
835}
836
837
838int class_interface_register(struct class_interface *class_intf)
839{
840	struct class *parent;
841	struct class_device *class_dev;
842	struct device *dev;
843
844	if (!class_intf || !class_intf->class)
845		return -ENODEV;
846
847	parent = class_get(class_intf->class);
848	if (!parent)
849		return -EINVAL;
850
851	down(&parent->sem);
852	list_add_tail(&class_intf->node, &parent->interfaces);
853	if (class_intf->add) {
854		list_for_each_entry(class_dev, &parent->children, node)
855			class_intf->add(class_dev, class_intf);
856	}
857	if (class_intf->add_dev) {
858		list_for_each_entry(dev, &parent->devices, node)
859			class_intf->add_dev(dev, class_intf);
860	}
861	up(&parent->sem);
862
863	return 0;
864}
865
866void class_interface_unregister(struct class_interface *class_intf)
867{
868	struct class * parent = class_intf->class;
869	struct class_device *class_dev;
870	struct device *dev;
871
872	if (!parent)
873		return;
874
875	down(&parent->sem);
876	list_del_init(&class_intf->node);
877	if (class_intf->remove) {
878		list_for_each_entry(class_dev, &parent->children, node)
879			class_intf->remove(class_dev, class_intf);
880	}
881	if (class_intf->remove_dev) {
882		list_for_each_entry(dev, &parent->devices, node)
883			class_intf->remove_dev(dev, class_intf);
884	}
885	up(&parent->sem);
886
887	class_put(parent);
888}
889
890int __init classes_init(void)
891{
892	int retval;
893
894	retval = subsystem_register(&class_subsys);
895	if (retval)
896		return retval;
897
898	/* ick, this is ugly, the things we go through to keep from showing up
899	 * in sysfs... */
900	subsystem_init(&class_obj_subsys);
901	if (!class_obj_subsys.kobj.parent)
902		class_obj_subsys.kobj.parent = &class_obj_subsys.kobj;
903	return 0;
904}
905
906EXPORT_SYMBOL_GPL(class_create_file);
907EXPORT_SYMBOL_GPL(class_remove_file);
908EXPORT_SYMBOL_GPL(class_register);
909EXPORT_SYMBOL_GPL(class_unregister);
910EXPORT_SYMBOL_GPL(class_create);
911EXPORT_SYMBOL_GPL(class_destroy);
912
913EXPORT_SYMBOL_GPL(class_device_register);
914EXPORT_SYMBOL_GPL(class_device_unregister);
915EXPORT_SYMBOL_GPL(class_device_initialize);
916EXPORT_SYMBOL_GPL(class_device_add);
917EXPORT_SYMBOL_GPL(class_device_del);
918EXPORT_SYMBOL_GPL(class_device_get);
919EXPORT_SYMBOL_GPL(class_device_put);
920EXPORT_SYMBOL_GPL(class_device_create);
921EXPORT_SYMBOL_GPL(class_device_destroy);
922EXPORT_SYMBOL_GPL(class_device_create_file);
923EXPORT_SYMBOL_GPL(class_device_remove_file);
924EXPORT_SYMBOL_GPL(class_device_create_bin_file);
925EXPORT_SYMBOL_GPL(class_device_remove_bin_file);
926
927EXPORT_SYMBOL_GPL(class_interface_register);
928EXPORT_SYMBOL_GPL(class_interface_unregister);
929