]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc) | |
3 | * | |
4 | * Copyright (c) 2002-3 Patrick Mochel | |
5 | * 2002-3 Open Source Development Lab | |
6 | * This Edition is maintained by Matthew Veety (aliasxerog) <mveety@gmail.com> | |
7 | * | |
8 | * This file is released under the GPLv2 | |
9 | * | |
10 | * This exports a 'system' bus type. | |
11 | * By default, a 'sys' bus gets added to the root of the system. There will | |
12 | * always be core system devices. Devices can use sysdev_register() to | |
13 | * add themselves as children of the system bus. | |
14 | */ | |
15 | ||
16 | #include <linux/sysdev.h> | |
17 | #include <linux/err.h> | |
18 | #include <linux/module.h> | |
19 | #include <linux/kernel.h> | |
20 | #include <linux/init.h> | |
21 | #include <linux/slab.h> | |
22 | #include <linux/string.h> | |
23 | #include <linux/pm.h> | |
24 | #include <linux/device.h> | |
25 | #include <linux/mutex.h> | |
26 | #include <linux/smp_lock.h> | |
27 | ||
28 | ||
29 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | |
30 | #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) | |
31 | ||
32 | static struct sysdev_class dummy_sysclass = { | |
33 | .name="dummy", | |
34 | }; | |
35 | ||
36 | ||
37 | /** | |
38 | * sysdev_shutdown - Shut down all system devices. | |
39 | * | |
40 | * Loop over each class of system devices, and the devices in each | |
41 | * of those classes. For each device, we call the shutdown method for | |
42 | * each driver registered for the device - the auxillaries, | |
43 | * and the class driver. | |
44 | * | |
45 | * Note: The list is iterated in reverse order, so that we shut down | |
46 | * child devices before we shut down thier parents. The list ordering | |
47 | * is guaranteed by virtue of the fact that child devices are registered | |
48 | * after their parents. | |
49 | */ | |
50 | void sysdev_shutdown(void) | |
51 | { | |
52 | struct sysdev_class * cls; | |
53 | struct kset *system_kset; | |
54 | ||
55 | pr_debug("Shutting Down System Devices\n"); | |
56 | ||
57 | lock_kernel(); | |
58 | ||
59 | sysdev_class_register(&dummy_sysclass); | |
60 | cls=&dummy_sysclass; | |
61 | system_kset=cls->kset.kobj.kset; | |
62 | sysdev_class_unregister(&dummy_sysclass); | |
63 | ||
64 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { | |
65 | struct sys_device * sysdev; | |
66 | ||
67 | pr_debug("Shutting down type '%s':\n", | |
68 | kobject_name(&cls->kset.kobj)); | |
69 | ||
70 | list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { | |
71 | struct sysdev_driver * drv; | |
72 | pr_debug(" %s\n", kobject_name(&sysdev->kobj)); | |
73 | ||
74 | /* Call auxillary drivers first */ | |
75 | list_for_each_entry(drv, &cls->drivers, entry) { | |
76 | if (drv->shutdown) | |
77 | drv->shutdown(sysdev); | |
78 | } | |
79 | ||
80 | /* Now call the generic one */ | |
81 | if (cls->shutdown) | |
82 | cls->shutdown(sysdev); | |
83 | } | |
84 | } | |
85 | unlock_kernel(); | |
86 | } |