Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/base/sys.c (Version 2.6.11.8) and /linux/drivers/base/sys.c (Version 2.6.25)


  1 /*                                                  1 /*
  2  * sys.c - pseudo-bus for system 'devices' (cp      2  * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
  3  *                                                  3  *
  4  * Copyright (c) 2002-3 Patrick Mochel              4  * Copyright (c) 2002-3 Patrick Mochel
  5  *               2002-3 Open Source Developmen      5  *               2002-3 Open Source Development Lab
  6  *                                                  6  *
  7  * This file is released under the GPLv2            7  * This file is released under the GPLv2
  8  *                                                  8  *
  9  * This exports a 'system' bus type.                9  * This exports a 'system' bus type.
 10  * By default, a 'sys' bus gets added to the r     10  * By default, a 'sys' bus gets added to the root of the system. There will
 11  * always be core system devices. Devices can      11  * always be core system devices. Devices can use sysdev_register() to
 12  * add themselves as children of the system bu     12  * add themselves as children of the system bus.
 13  */                                                13  */
 14                                                    14 
 15 #include <linux/config.h>                      << 
 16 #include <linux/sysdev.h>                          15 #include <linux/sysdev.h>
 17 #include <linux/err.h>                             16 #include <linux/err.h>
 18 #include <linux/module.h>                          17 #include <linux/module.h>
 19 #include <linux/kernel.h>                          18 #include <linux/kernel.h>
 20 #include <linux/init.h>                            19 #include <linux/init.h>
 21 #include <linux/slab.h>                            20 #include <linux/slab.h>
 22 #include <linux/string.h>                          21 #include <linux/string.h>
                                                   >>  22 #include <linux/pm.h>
                                                   >>  23 #include <linux/device.h>
                                                   >>  24 #include <linux/mutex.h>
 23                                                    25 
 24                                                !!  26 #include "base.h"
 25 extern struct subsystem devices_subsys;        << 
 26                                                    27 
 27 #define to_sysdev(k) container_of(k, struct sy     28 #define to_sysdev(k) container_of(k, struct sys_device, kobj)
 28 #define to_sysdev_attr(a) container_of(a, stru     29 #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr)
 29                                                    30 
 30                                                    31 
 31 static ssize_t                                     32 static ssize_t
 32 sysdev_show(struct kobject * kobj, struct attr     33 sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
 33 {                                                  34 {
 34         struct sys_device * sysdev = to_sysdev     35         struct sys_device * sysdev = to_sysdev(kobj);
 35         struct sysdev_attribute * sysdev_attr      36         struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
 36                                                    37 
 37         if (sysdev_attr->show)                     38         if (sysdev_attr->show)
 38                 return sysdev_attr->show(sysde     39                 return sysdev_attr->show(sysdev, buffer);
 39         return 0;                              !!  40         return -EIO;
 40 }                                                  41 }
 41                                                    42 
 42                                                    43 
 43 static ssize_t                                     44 static ssize_t
 44 sysdev_store(struct kobject * kobj, struct att     45 sysdev_store(struct kobject * kobj, struct attribute * attr,
 45              const char * buffer, size_t count     46              const char * buffer, size_t count)
 46 {                                                  47 {
 47         struct sys_device * sysdev = to_sysdev     48         struct sys_device * sysdev = to_sysdev(kobj);
 48         struct sysdev_attribute * sysdev_attr      49         struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
 49                                                    50 
 50         if (sysdev_attr->store)                    51         if (sysdev_attr->store)
 51                 return sysdev_attr->store(sysd     52                 return sysdev_attr->store(sysdev, buffer, count);
 52         return 0;                              !!  53         return -EIO;
 53 }                                                  54 }
 54                                                    55 
 55 static struct sysfs_ops sysfs_ops = {              56 static struct sysfs_ops sysfs_ops = {
 56         .show   = sysdev_show,                     57         .show   = sysdev_show,
 57         .store  = sysdev_store,                    58         .store  = sysdev_store,
 58 };                                                 59 };
 59                                                    60 
 60 static struct kobj_type ktype_sysdev = {           61 static struct kobj_type ktype_sysdev = {
 61         .sysfs_ops      = &sysfs_ops,              62         .sysfs_ops      = &sysfs_ops,
 62 };                                                 63 };
 63                                                    64 
 64                                                    65 
 65 int sysdev_create_file(struct sys_device * s,      66 int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
 66 {                                                  67 {
 67         return sysfs_create_file(&s->kobj, &a-     68         return sysfs_create_file(&s->kobj, &a->attr);
 68 }                                                  69 }
 69                                                    70 
 70                                                    71 
 71 void sysdev_remove_file(struct sys_device * s,     72 void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
 72 {                                                  73 {
 73         sysfs_remove_file(&s->kobj, &a->attr);     74         sysfs_remove_file(&s->kobj, &a->attr);
 74 }                                                  75 }
 75                                                    76 
 76 EXPORT_SYMBOL_GPL(sysdev_create_file);             77 EXPORT_SYMBOL_GPL(sysdev_create_file);
 77 EXPORT_SYMBOL_GPL(sysdev_remove_file);             78 EXPORT_SYMBOL_GPL(sysdev_remove_file);
 78                                                    79 
 79 /*                                             !!  80 #define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj)
 80  * declare system_subsys                       !!  81 #define to_sysdev_class_attr(a) container_of(a, \
 81  */                                            !!  82         struct sysdev_class_attribute, attr)
 82 decl_subsys(system, &ktype_sysdev, NULL);      !!  83 
                                                   >>  84 static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
                                                   >>  85                                  char *buffer)
                                                   >>  86 {
                                                   >>  87         struct sysdev_class * class = to_sysdev_class(kobj);
                                                   >>  88         struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
                                                   >>  89 
                                                   >>  90         if (class_attr->show)
                                                   >>  91                 return class_attr->show(class, buffer);
                                                   >>  92         return -EIO;
                                                   >>  93 }
                                                   >>  94 
                                                   >>  95 static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
                                                   >>  96                                   const char *buffer, size_t count)
                                                   >>  97 {
                                                   >>  98         struct sysdev_class * class = to_sysdev_class(kobj);
                                                   >>  99         struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
                                                   >> 100 
                                                   >> 101         if (class_attr->store)
                                                   >> 102                 return class_attr->store(class, buffer, count);
                                                   >> 103         return -EIO;
                                                   >> 104 }
                                                   >> 105 
                                                   >> 106 static struct sysfs_ops sysfs_class_ops = {
                                                   >> 107         .show   = sysdev_class_show,
                                                   >> 108         .store  = sysdev_class_store,
                                                   >> 109 };
                                                   >> 110 
                                                   >> 111 static struct kobj_type ktype_sysdev_class = {
                                                   >> 112         .sysfs_ops      = &sysfs_class_ops,
                                                   >> 113 };
                                                   >> 114 
                                                   >> 115 int sysdev_class_create_file(struct sysdev_class *c,
                                                   >> 116                              struct sysdev_class_attribute *a)
                                                   >> 117 {
                                                   >> 118         return sysfs_create_file(&c->kset.kobj, &a->attr);
                                                   >> 119 }
                                                   >> 120 EXPORT_SYMBOL_GPL(sysdev_class_create_file);
                                                   >> 121 
                                                   >> 122 void sysdev_class_remove_file(struct sysdev_class *c,
                                                   >> 123                               struct sysdev_class_attribute *a)
                                                   >> 124 {
                                                   >> 125         sysfs_remove_file(&c->kset.kobj, &a->attr);
                                                   >> 126 }
                                                   >> 127 EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
                                                   >> 128 
                                                   >> 129 static struct kset *system_kset;
 83                                                   130 
 84 int sysdev_class_register(struct sysdev_class     131 int sysdev_class_register(struct sysdev_class * cls)
 85 {                                                 132 {
 86         pr_debug("Registering sysdev class '%s    133         pr_debug("Registering sysdev class '%s'\n",
 87                  kobject_name(&cls->kset.kobj)    134                  kobject_name(&cls->kset.kobj));
 88         INIT_LIST_HEAD(&cls->drivers);            135         INIT_LIST_HEAD(&cls->drivers);
 89         cls->kset.subsys = &system_subsys;     !! 136         memset(&cls->kset.kobj, 0x00, sizeof(struct kobject));
 90         kset_set_kset_s(cls, system_subsys);   !! 137         cls->kset.kobj.parent = &system_kset->kobj;
                                                   >> 138         cls->kset.kobj.ktype = &ktype_sysdev_class;
                                                   >> 139         cls->kset.kobj.kset = system_kset;
                                                   >> 140         kobject_set_name(&cls->kset.kobj, cls->name);
 91         return kset_register(&cls->kset);         141         return kset_register(&cls->kset);
 92 }                                                 142 }
 93                                                   143 
 94 void sysdev_class_unregister(struct sysdev_cla    144 void sysdev_class_unregister(struct sysdev_class * cls)
 95 {                                                 145 {
 96         pr_debug("Unregistering sysdev class '    146         pr_debug("Unregistering sysdev class '%s'\n",
 97                  kobject_name(&cls->kset.kobj)    147                  kobject_name(&cls->kset.kobj));
 98         kset_unregister(&cls->kset);              148         kset_unregister(&cls->kset);
 99 }                                                 149 }
100                                                   150 
101 EXPORT_SYMBOL_GPL(sysdev_class_register);         151 EXPORT_SYMBOL_GPL(sysdev_class_register);
102 EXPORT_SYMBOL_GPL(sysdev_class_unregister);       152 EXPORT_SYMBOL_GPL(sysdev_class_unregister);
103                                                   153 
104                                                !! 154 static DEFINE_MUTEX(sysdev_drivers_lock);
105 static LIST_HEAD(global_drivers);              << 
106                                                   155 
107 /**                                               156 /**
108  *      sysdev_driver_register - Register auxi    157  *      sysdev_driver_register - Register auxillary driver
109  *      @cls:   Device class driver belongs to !! 158  *      @cls:   Device class driver belongs to.
110  *      @drv:   Driver.                           159  *      @drv:   Driver.
111  *                                                160  *
112  *      If @cls is valid, then @drv is inserte !! 161  *      @drv is inserted into @cls->drivers to be
113  *      called on each operation on devices of    162  *      called on each operation on devices of that class. The refcount
114  *      of @cls is incremented.                   163  *      of @cls is incremented.
115  *      Otherwise, @drv is inserted into globa << 
116  *      each device.                           << 
117  */                                               164  */
118                                                   165 
119 int sysdev_driver_register(struct sysdev_class !! 166 int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
120                            struct sysdev_drive << 
121 {                                                 167 {
122         down_write(&system_subsys.rwsem);      !! 168         int err = 0;
                                                   >> 169 
                                                   >> 170         mutex_lock(&sysdev_drivers_lock);
123         if (cls && kset_get(&cls->kset)) {        171         if (cls && kset_get(&cls->kset)) {
124                 list_add_tail(&drv->entry, &cl    172                 list_add_tail(&drv->entry, &cls->drivers);
125                                                   173 
126                 /* If devices of this class al    174                 /* If devices of this class already exist, tell the driver */
127                 if (drv->add) {                   175                 if (drv->add) {
128                         struct sys_device *dev    176                         struct sys_device *dev;
129                         list_for_each_entry(de    177                         list_for_each_entry(dev, &cls->kset.list, kobj.entry)
130                                 drv->add(dev);    178                                 drv->add(dev);
131                 }                                 179                 }
132         } else                                 !! 180         } else {
133                 list_add_tail(&drv->entry, &gl !! 181                 err = -EINVAL;
134         up_write(&system_subsys.rwsem);        !! 182                 printk(KERN_ERR "%s: invalid device class\n", __FUNCTION__);
135         return 0;                              !! 183                 WARN_ON(1);
                                                   >> 184         }
                                                   >> 185         mutex_unlock(&sysdev_drivers_lock);
                                                   >> 186         return err;
136 }                                                 187 }
137                                                   188 
138                                                   189 
139 /**                                               190 /**
140  *      sysdev_driver_unregister - Remove an a    191  *      sysdev_driver_unregister - Remove an auxillary driver.
141  *      @cls:   Class driver belongs to.          192  *      @cls:   Class driver belongs to.
142  *      @drv:   Driver.                           193  *      @drv:   Driver.
143  */                                               194  */
144 void sysdev_driver_unregister(struct sysdev_cl    195 void sysdev_driver_unregister(struct sysdev_class * cls,
145                               struct sysdev_dr    196                               struct sysdev_driver * drv)
146 {                                                 197 {
147         down_write(&system_subsys.rwsem);      !! 198         mutex_lock(&sysdev_drivers_lock);
148         list_del_init(&drv->entry);               199         list_del_init(&drv->entry);
149         if (cls) {                                200         if (cls) {
150                 if (drv->remove) {                201                 if (drv->remove) {
151                         struct sys_device *dev    202                         struct sys_device *dev;
152                         list_for_each_entry(de    203                         list_for_each_entry(dev, &cls->kset.list, kobj.entry)
153                                 drv->remove(de    204                                 drv->remove(dev);
154                 }                                 205                 }
155                 kset_put(&cls->kset);             206                 kset_put(&cls->kset);
156         }                                         207         }
157         up_write(&system_subsys.rwsem);        !! 208         mutex_unlock(&sysdev_drivers_lock);
158 }                                                 209 }
159                                                   210 
160 EXPORT_SYMBOL_GPL(sysdev_driver_register);        211 EXPORT_SYMBOL_GPL(sysdev_driver_register);
161 EXPORT_SYMBOL_GPL(sysdev_driver_unregister);      212 EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
162                                                   213 
163                                                   214 
164                                                   215 
165 /**                                               216 /**
166  *      sysdev_register - add a system device     217  *      sysdev_register - add a system device to the tree
167  *      @sysdev:        device in question        218  *      @sysdev:        device in question
168  *                                                219  *
169  */                                               220  */
170 int sysdev_register(struct sys_device * sysdev    221 int sysdev_register(struct sys_device * sysdev)
171 {                                                 222 {
172         int error;                                223         int error;
173         struct sysdev_class * cls = sysdev->cl    224         struct sysdev_class * cls = sysdev->cls;
174                                                   225 
175         if (!cls)                                 226         if (!cls)
176                 return -EINVAL;                   227                 return -EINVAL;
177                                                   228 
178         /* Make sure the kset is set */        !! 229         pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj));
179         sysdev->kobj.kset = &cls->kset;        << 
180                                                   230 
181         /* But make sure we point to the right !! 231         /* initialize the kobject to 0, in case it had previously been used */
182         sysdev->kobj.ktype = &ktype_sysdev;    !! 232         memset(&sysdev->kobj, 0x00, sizeof(struct kobject));
183         error = kobject_set_name(&sysdev->kobj << 
184                          kobject_name(&cls->ks << 
185         if (error)                             << 
186                 return error;                  << 
187                                                   233 
188         pr_debug("Registering sys device '%s'\ !! 234         /* Make sure the kset is set */
                                                   >> 235         sysdev->kobj.kset = &cls->kset;
189                                                   236 
190         /* Register the object */                 237         /* Register the object */
191         error = kobject_register(&sysdev->kobj !! 238         error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL,
                                                   >> 239                                      "%s%d", kobject_name(&cls->kset.kobj),
                                                   >> 240                                      sysdev->id);
192                                                   241 
193         if (!error) {                             242         if (!error) {
194                 struct sysdev_driver * drv;       243                 struct sysdev_driver * drv;
195                                                   244 
196                 down_write(&system_subsys.rwse !! 245                 mutex_lock(&sysdev_drivers_lock);
197                 /* Generic notification is imp    246                 /* Generic notification is implicit, because it's that
198                  * code that should have calle    247                  * code that should have called us.
199                  */                               248                  */
200                                                   249 
201                 /* Notify global drivers */    << 
202                 list_for_each_entry(drv, &glob << 
203                         if (drv->add)          << 
204                                 drv->add(sysde << 
205                 }                              << 
206                                                << 
207                 /* Notify class auxillary driv    250                 /* Notify class auxillary drivers */
208                 list_for_each_entry(drv, &cls-    251                 list_for_each_entry(drv, &cls->drivers, entry) {
209                         if (drv->add)             252                         if (drv->add)
210                                 drv->add(sysde    253                                 drv->add(sysdev);
211                 }                                 254                 }
212                 up_write(&system_subsys.rwsem) !! 255                 mutex_unlock(&sysdev_drivers_lock);
213         }                                         256         }
                                                   >> 257         kobject_uevent(&sysdev->kobj, KOBJ_ADD);
214         return error;                             258         return error;
215 }                                                 259 }
216                                                   260 
217 void sysdev_unregister(struct sys_device * sys    261 void sysdev_unregister(struct sys_device * sysdev)
218 {                                                 262 {
219         struct sysdev_driver * drv;               263         struct sysdev_driver * drv;
220                                                   264 
221         down_write(&system_subsys.rwsem);      !! 265         mutex_lock(&sysdev_drivers_lock);
222         list_for_each_entry(drv, &global_drive << 
223                 if (drv->remove)               << 
224                         drv->remove(sysdev);   << 
225         }                                      << 
226                                                << 
227         list_for_each_entry(drv, &sysdev->cls-    266         list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
228                 if (drv->remove)                  267                 if (drv->remove)
229                         drv->remove(sysdev);      268                         drv->remove(sysdev);
230         }                                         269         }
231         up_write(&system_subsys.rwsem);        !! 270         mutex_unlock(&sysdev_drivers_lock);
232                                                   271 
233         kobject_unregister(&sysdev->kobj);     !! 272         kobject_put(&sysdev->kobj);
234 }                                                 273 }
235                                                   274 
236                                                   275 
237                                                   276 
238 /**                                               277 /**
239  *      sysdev_shutdown - Shut down all system    278  *      sysdev_shutdown - Shut down all system devices.
240  *                                                279  *
241  *      Loop over each class of system devices    280  *      Loop over each class of system devices, and the devices in each
242  *      of those classes. For each device, we     281  *      of those classes. For each device, we call the shutdown method for
243  *      each driver registered for the device  !! 282  *      each driver registered for the device - the auxillaries,
244  *      and the class driver.                     283  *      and the class driver.
245  *                                                284  *
246  *      Note: The list is iterated in reverse     285  *      Note: The list is iterated in reverse order, so that we shut down
247  *      child devices before we shut down thie    286  *      child devices before we shut down thier parents. The list ordering
248  *      is guaranteed by virtue of the fact th    287  *      is guaranteed by virtue of the fact that child devices are registered
249  *      after their parents.                      288  *      after their parents.
250  */                                               289  */
251                                                   290 
252 void sysdev_shutdown(void)                        291 void sysdev_shutdown(void)
253 {                                                 292 {
254         struct sysdev_class * cls;                293         struct sysdev_class * cls;
255                                                   294 
256         pr_debug("Shutting Down System Devices    295         pr_debug("Shutting Down System Devices\n");
257                                                   296 
258         down_write(&system_subsys.rwsem);      !! 297         mutex_lock(&sysdev_drivers_lock);
259         list_for_each_entry_reverse(cls, &syst !! 298         list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
260                                     kset.kobj. << 
261                 struct sys_device * sysdev;       299                 struct sys_device * sysdev;
262                                                   300 
263                 pr_debug("Shutting down type '    301                 pr_debug("Shutting down type '%s':\n",
264                          kobject_name(&cls->ks    302                          kobject_name(&cls->kset.kobj));
265                                                   303 
266                 list_for_each_entry(sysdev, &c    304                 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
267                         struct sysdev_driver *    305                         struct sysdev_driver * drv;
268                         pr_debug(" %s\n", kobj    306                         pr_debug(" %s\n", kobject_name(&sysdev->kobj));
269                                                   307 
270                         /* Call global drivers !! 308                         /* Call auxillary drivers first */
271                         list_for_each_entry(dr << 
272                                 if (drv->shutd << 
273                                         drv->s << 
274                         }                      << 
275                                                << 
276                         /* Call auxillary driv << 
277                         list_for_each_entry(dr    309                         list_for_each_entry(drv, &cls->drivers, entry) {
278                                 if (drv->shutd    310                                 if (drv->shutdown)
279                                         drv->s    311                                         drv->shutdown(sysdev);
280                         }                         312                         }
281                                                   313 
282                         /* Now call the generi    314                         /* Now call the generic one */
283                         if (cls->shutdown)        315                         if (cls->shutdown)
284                                 cls->shutdown(    316                                 cls->shutdown(sysdev);
285                 }                                 317                 }
286         }                                         318         }
287         up_write(&system_subsys.rwsem);        !! 319         mutex_unlock(&sysdev_drivers_lock);
288 }                                                 320 }
289                                                   321 
                                                   >> 322 static void __sysdev_resume(struct sys_device *dev)
                                                   >> 323 {
                                                   >> 324         struct sysdev_class *cls = dev->cls;
                                                   >> 325         struct sysdev_driver *drv;
                                                   >> 326 
                                                   >> 327         /* First, call the class-specific one */
                                                   >> 328         if (cls->resume)
                                                   >> 329                 cls->resume(dev);
                                                   >> 330 
                                                   >> 331         /* Call auxillary drivers next. */
                                                   >> 332         list_for_each_entry(drv, &cls->drivers, entry) {
                                                   >> 333                 if (drv->resume)
                                                   >> 334                         drv->resume(dev);
                                                   >> 335         }
                                                   >> 336 }
290                                                   337 
291 /**                                               338 /**
292  *      sysdev_suspend - Suspend all system de    339  *      sysdev_suspend - Suspend all system devices.
293  *      @state:         Power state to enter.     340  *      @state:         Power state to enter.
294  *                                                341  *
295  *      We perform an almost identical operati    342  *      We perform an almost identical operation as sys_device_shutdown()
296  *      above, though calling ->suspend() inst    343  *      above, though calling ->suspend() instead. Interrupts are disabled
297  *      when this called. Devices are responsi    344  *      when this called. Devices are responsible for both saving state and
298  *      quiescing or powering down the device.    345  *      quiescing or powering down the device.
299  *                                                346  *
300  *      This is only called by the device PM c    347  *      This is only called by the device PM core, so we let them handle
301  *      all synchronization.                      348  *      all synchronization.
302  */                                               349  */
303                                                   350 
304 int sysdev_suspend(u32 state)                  !! 351 int sysdev_suspend(pm_message_t state)
305 {                                                 352 {
306         struct sysdev_class * cls;                353         struct sysdev_class * cls;
                                                   >> 354         struct sys_device *sysdev, *err_dev;
                                                   >> 355         struct sysdev_driver *drv, *err_drv;
                                                   >> 356         int ret;
307                                                   357 
308         pr_debug("Suspending System Devices\n"    358         pr_debug("Suspending System Devices\n");
309                                                   359 
310         list_for_each_entry_reverse(cls, &syst !! 360         list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
311                                     kset.kobj. << 
312                 struct sys_device * sysdev;    << 
313                                                << 
314                 pr_debug("Suspending type '%s'    361                 pr_debug("Suspending type '%s':\n",
315                          kobject_name(&cls->ks    362                          kobject_name(&cls->kset.kobj));
316                                                   363 
317                 list_for_each_entry(sysdev, &c    364                 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
318                         struct sysdev_driver * << 
319                         pr_debug(" %s\n", kobj    365                         pr_debug(" %s\n", kobject_name(&sysdev->kobj));
320                                                   366 
321                         /* Call global drivers !! 367                         /* Call auxillary drivers first */
322                         list_for_each_entry(dr << 
323                                 if (drv->suspe << 
324                                         drv->s << 
325                         }                      << 
326                                                << 
327                         /* Call auxillary driv << 
328                         list_for_each_entry(dr    368                         list_for_each_entry(drv, &cls->drivers, entry) {
329                                 if (drv->suspe !! 369                                 if (drv->suspend) {
330                                         drv->s !! 370                                         ret = drv->suspend(sysdev, state);
                                                   >> 371                                         if (ret)
                                                   >> 372                                                 goto aux_driver;
                                                   >> 373                                 }
331                         }                         374                         }
332                                                   375 
333                         /* Now call the generi    376                         /* Now call the generic one */
334                         if (cls->suspend)      !! 377                         if (cls->suspend) {
335                                 cls->suspend(s !! 378                                 ret = cls->suspend(sysdev, state);
                                                   >> 379                                 if (ret)
                                                   >> 380                                         goto cls_driver;
                                                   >> 381                         }
336                 }                                 382                 }
337         }                                         383         }
338         return 0;                                 384         return 0;
                                                   >> 385         /* resume current sysdev */
                                                   >> 386 cls_driver:
                                                   >> 387         drv = NULL;
                                                   >> 388         printk(KERN_ERR "Class suspend failed for %s\n",
                                                   >> 389                 kobject_name(&sysdev->kobj));
                                                   >> 390 
                                                   >> 391 aux_driver:
                                                   >> 392         if (drv)
                                                   >> 393                 printk(KERN_ERR "Class driver suspend failed for %s\n",
                                                   >> 394                                 kobject_name(&sysdev->kobj));
                                                   >> 395         list_for_each_entry(err_drv, &cls->drivers, entry) {
                                                   >> 396                 if (err_drv == drv)
                                                   >> 397                         break;
                                                   >> 398                 if (err_drv->resume)
                                                   >> 399                         err_drv->resume(sysdev);
                                                   >> 400         }
                                                   >> 401 
                                                   >> 402         /* resume other sysdevs in current class */
                                                   >> 403         list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
                                                   >> 404                 if (err_dev == sysdev)
                                                   >> 405                         break;
                                                   >> 406                 pr_debug(" %s\n", kobject_name(&err_dev->kobj));
                                                   >> 407                 __sysdev_resume(err_dev);
                                                   >> 408         }
                                                   >> 409 
                                                   >> 410         /* resume other classes */
                                                   >> 411         list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) {
                                                   >> 412                 list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
                                                   >> 413                         pr_debug(" %s\n", kobject_name(&err_dev->kobj));
                                                   >> 414                         __sysdev_resume(err_dev);
                                                   >> 415                 }
                                                   >> 416         }
                                                   >> 417         return ret;
339 }                                                 418 }
340                                                   419 
341                                                   420 
342 /**                                               421 /**
343  *      sysdev_resume - Bring system devices b    422  *      sysdev_resume - Bring system devices back to life.
344  *                                                423  *
345  *      Similar to sys_device_suspend(), but w    424  *      Similar to sys_device_suspend(), but we iterate the list forwards
346  *      to guarantee that parent devices are r    425  *      to guarantee that parent devices are resumed before their children.
347  *                                                426  *
348  *      Note: Interrupts are disabled when cal    427  *      Note: Interrupts are disabled when called.
349  */                                               428  */
350                                                   429 
351 int sysdev_resume(void)                           430 int sysdev_resume(void)
352 {                                                 431 {
353         struct sysdev_class * cls;                432         struct sysdev_class * cls;
354                                                   433 
355         pr_debug("Resuming System Devices\n");    434         pr_debug("Resuming System Devices\n");
356                                                   435 
357         list_for_each_entry(cls, &system_subsy !! 436         list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
358                 struct sys_device * sysdev;       437                 struct sys_device * sysdev;
359                                                   438 
360                 pr_debug("Resuming type '%s':\    439                 pr_debug("Resuming type '%s':\n",
361                          kobject_name(&cls->ks    440                          kobject_name(&cls->kset.kobj));
362                                                   441 
363                 list_for_each_entry(sysdev, &c    442                 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
364                         struct sysdev_driver * << 
365                         pr_debug(" %s\n", kobj    443                         pr_debug(" %s\n", kobject_name(&sysdev->kobj));
366                                                   444 
367                         /* First, call the cla !! 445                         __sysdev_resume(sysdev);
368                         if (cls->resume)       << 
369                                 cls->resume(sy << 
370                                                << 
371                         /* Call auxillary driv << 
372                         list_for_each_entry(dr << 
373                                 if (drv->resum << 
374                                         drv->r << 
375                         }                      << 
376                                                << 
377                         /* Call global drivers << 
378                         list_for_each_entry(dr << 
379                                 if (drv->resum << 
380                                         drv->r << 
381                         }                      << 
382                                                << 
383                 }                                 446                 }
384         }                                         447         }
385         return 0;                                 448         return 0;
386 }                                                 449 }
387                                                   450 
388                                                   451 
389 int __init system_bus_init(void)                  452 int __init system_bus_init(void)
390 {                                                 453 {
391         system_subsys.kset.kobj.parent = &devi !! 454         system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
392         return subsystem_register(&system_subs !! 455         if (!system_kset)
                                                   >> 456                 return -ENOMEM;
                                                   >> 457         return 0;
393 }                                                 458 }
394                                                   459 
395 EXPORT_SYMBOL_GPL(sysdev_register);               460 EXPORT_SYMBOL_GPL(sysdev_register);
396 EXPORT_SYMBOL_GPL(sysdev_unregister);             461 EXPORT_SYMBOL_GPL(sysdev_unregister);
397                                                   462 
  This page was automatically generated by the LXR engine.