~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/base/sys.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
166
166
 
167
167
static DEFINE_MUTEX(sysdev_drivers_lock);
168
168
 
 
169
/*
 
170
 * @dev != NULL means that we're unwinding because some drv->add()
 
171
 * failed for some reason. You need to grab sysdev_drivers_lock before
 
172
 * calling this.
 
173
 */
 
174
static void __sysdev_driver_remove(struct sysdev_class *cls,
 
175
                                   struct sysdev_driver *drv,
 
176
                                   struct sys_device *from_dev)
 
177
{
 
178
        struct sys_device *dev = from_dev;
 
179
 
 
180
        list_del_init(&drv->entry);
 
181
        if (!cls)
 
182
                return;
 
183
 
 
184
        if (!drv->remove)
 
185
                goto kset_put;
 
186
 
 
187
        if (dev)
 
188
                list_for_each_entry_continue_reverse(dev, &cls->kset.list,
 
189
                                                     kobj.entry)
 
190
                        drv->remove(dev);
 
191
        else
 
192
                list_for_each_entry(dev, &cls->kset.list, kobj.entry)
 
193
                        drv->remove(dev);
 
194
 
 
195
kset_put:
 
196
        kset_put(&cls->kset);
 
197
}
 
198
 
169
199
/**
170
 
 *      sysdev_driver_register - Register auxillary driver
 
200
 *      sysdev_driver_register - Register auxiliary driver
171
201
 *      @cls:   Device class driver belongs to.
172
202
 *      @drv:   Driver.
173
203
 *
175
205
 *      called on each operation on devices of that class. The refcount
176
206
 *      of @cls is incremented.
177
207
 */
178
 
 
179
208
int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
180
209
{
 
210
        struct sys_device *dev = NULL;
181
211
        int err = 0;
182
212
 
183
213
        if (!cls) {
184
 
                WARN(1, KERN_WARNING "sysdev: invalid class passed to "
185
 
                        "sysdev_driver_register!\n");
 
214
                WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n",
 
215
                        __func__);
186
216
                return -EINVAL;
187
217
        }
188
218
 
198
228
 
199
229
                /* If devices of this class already exist, tell the driver */
200
230
                if (drv->add) {
201
 
                        struct sys_device *dev;
202
 
                        list_for_each_entry(dev, &cls->kset.list, kobj.entry)
203
 
                                drv->add(dev);
 
231
                        list_for_each_entry(dev, &cls->kset.list, kobj.entry) {
 
232
                                err = drv->add(dev);
 
233
                                if (err)
 
234
                                        goto unwind;
 
235
                        }
204
236
                }
205
237
        } else {
206
238
                err = -EINVAL;
207
239
                WARN(1, KERN_ERR "%s: invalid device class\n", __func__);
208
240
        }
 
241
 
 
242
        goto unlock;
 
243
 
 
244
unwind:
 
245
        __sysdev_driver_remove(cls, drv, dev);
 
246
 
 
247
unlock:
209
248
        mutex_unlock(&sysdev_drivers_lock);
210
249
        return err;
211
250
}
212
251
 
213
 
 
214
252
/**
215
 
 *      sysdev_driver_unregister - Remove an auxillary driver.
 
253
 *      sysdev_driver_unregister - Remove an auxiliary driver.
216
254
 *      @cls:   Class driver belongs to.
217
255
 *      @drv:   Driver.
218
256
 */
220
258
                              struct sysdev_driver *drv)
221
259
{
222
260
        mutex_lock(&sysdev_drivers_lock);
223
 
        list_del_init(&drv->entry);
224
 
        if (cls) {
225
 
                if (drv->remove) {
226
 
                        struct sys_device *dev;
227
 
                        list_for_each_entry(dev, &cls->kset.list, kobj.entry)
228
 
                                drv->remove(dev);
229
 
                }
230
 
                kset_put(&cls->kset);
231
 
        }
 
261
        __sysdev_driver_remove(cls, drv, NULL);
232
262
        mutex_unlock(&sysdev_drivers_lock);
233
263
}
234
 
 
235
264
EXPORT_SYMBOL_GPL(sysdev_driver_register);
236
265
EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
237
266
 
238
 
 
239
 
 
240
267
/**
241
268
 *      sysdev_register - add a system device to the tree
242
269
 *      @sysdev:        device in question
275
302
                 * code that should have called us.
276
303
                 */
277
304
 
278
 
                /* Notify class auxillary drivers */
 
305
                /* Notify class auxiliary drivers */
279
306
                list_for_each_entry(drv, &cls->drivers, entry) {
280
307
                        if (drv->add)
281
308
                                drv->add(sysdev);
301
328
        kobject_put(&sysdev->kobj);
302
329
}
303
330
 
304
 
 
305
 
 
306
 
/**
307
 
 *      sysdev_shutdown - Shut down all system devices.
308
 
 *
309
 
 *      Loop over each class of system devices, and the devices in each
310
 
 *      of those classes. For each device, we call the shutdown method for
311
 
 *      each driver registered for the device - the auxillaries,
312
 
 *      and the class driver.
313
 
 *
314
 
 *      Note: The list is iterated in reverse order, so that we shut down
315
 
 *      child devices before we shut down their parents. The list ordering
316
 
 *      is guaranteed by virtue of the fact that child devices are registered
317
 
 *      after their parents.
318
 
 */
319
 
void sysdev_shutdown(void)
320
 
{
321
 
        struct sysdev_class *cls;
322
 
 
323
 
        pr_debug("Shutting Down System Devices\n");
324
 
 
325
 
        mutex_lock(&sysdev_drivers_lock);
326
 
        list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
327
 
                struct sys_device *sysdev;
328
 
 
329
 
                pr_debug("Shutting down type '%s':\n",
330
 
                         kobject_name(&cls->kset.kobj));
331
 
 
332
 
                list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
333
 
                        struct sysdev_driver *drv;
334
 
                        pr_debug(" %s\n", kobject_name(&sysdev->kobj));
335
 
 
336
 
                        /* Call auxillary drivers first */
337
 
                        list_for_each_entry(drv, &cls->drivers, entry) {
338
 
                                if (drv->shutdown)
339
 
                                        drv->shutdown(sysdev);
340
 
                        }
341
 
 
342
 
                        /* Now call the generic one */
343
 
                        if (cls->shutdown)
344
 
                                cls->shutdown(sysdev);
345
 
                }
346
 
        }
347
 
        mutex_unlock(&sysdev_drivers_lock);
348
 
}
349
 
 
350
 
static void __sysdev_resume(struct sys_device *dev)
351
 
{
352
 
        struct sysdev_class *cls = dev->cls;
353
 
        struct sysdev_driver *drv;
354
 
 
355
 
        /* First, call the class-specific one */
356
 
        if (cls->resume)
357
 
                cls->resume(dev);
358
 
        WARN_ONCE(!irqs_disabled(),
359
 
                "Interrupts enabled after %pF\n", cls->resume);
360
 
 
361
 
        /* Call auxillary drivers next. */
362
 
        list_for_each_entry(drv, &cls->drivers, entry) {
363
 
                if (drv->resume)
364
 
                        drv->resume(dev);
365
 
                WARN_ONCE(!irqs_disabled(),
366
 
                        "Interrupts enabled after %pF\n", drv->resume);
367
 
        }
368
 
}
369
 
 
370
 
/**
371
 
 *      sysdev_suspend - Suspend all system devices.
372
 
 *      @state:         Power state to enter.
373
 
 *
374
 
 *      We perform an almost identical operation as sysdev_shutdown()
375
 
 *      above, though calling ->suspend() instead. Interrupts are disabled
376
 
 *      when this called. Devices are responsible for both saving state and
377
 
 *      quiescing or powering down the device.
378
 
 *
379
 
 *      This is only called by the device PM core, so we let them handle
380
 
 *      all synchronization.
381
 
 */
382
 
int sysdev_suspend(pm_message_t state)
383
 
{
384
 
        struct sysdev_class *cls;
385
 
        struct sys_device *sysdev, *err_dev;
386
 
        struct sysdev_driver *drv, *err_drv;
387
 
        int ret;
388
 
 
389
 
        pr_debug("Checking wake-up interrupts\n");
390
 
 
391
 
        /* Return error code if there are any wake-up interrupts pending */
392
 
        ret = check_wakeup_irqs();
393
 
        if (ret)
394
 
                return ret;
395
 
 
396
 
        WARN_ONCE(!irqs_disabled(),
397
 
                "Interrupts enabled while suspending system devices\n");
398
 
 
399
 
        pr_debug("Suspending System Devices\n");
400
 
 
401
 
        list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
402
 
                pr_debug("Suspending type '%s':\n",
403
 
                         kobject_name(&cls->kset.kobj));
404
 
 
405
 
                list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
406
 
                        pr_debug(" %s\n", kobject_name(&sysdev->kobj));
407
 
 
408
 
                        /* Call auxillary drivers first */
409
 
                        list_for_each_entry(drv, &cls->drivers, entry) {
410
 
                                if (drv->suspend) {
411
 
                                        ret = drv->suspend(sysdev, state);
412
 
                                        if (ret)
413
 
                                                goto aux_driver;
414
 
                                }
415
 
                                WARN_ONCE(!irqs_disabled(),
416
 
                                        "Interrupts enabled after %pF\n",
417
 
                                        drv->suspend);
418
 
                        }
419
 
 
420
 
                        /* Now call the generic one */
421
 
                        if (cls->suspend) {
422
 
                                ret = cls->suspend(sysdev, state);
423
 
                                if (ret)
424
 
                                        goto cls_driver;
425
 
                                WARN_ONCE(!irqs_disabled(),
426
 
                                        "Interrupts enabled after %pF\n",
427
 
                                        cls->suspend);
428
 
                        }
429
 
                }
430
 
        }
431
 
        return 0;
432
 
        /* resume current sysdev */
433
 
cls_driver:
434
 
        drv = NULL;
435
 
        printk(KERN_ERR "Class suspend failed for %s: %d\n",
436
 
                kobject_name(&sysdev->kobj), ret);
437
 
 
438
 
aux_driver:
439
 
        if (drv)
440
 
                printk(KERN_ERR "Class driver suspend failed for %s: %d\n",
441
 
                                kobject_name(&sysdev->kobj), ret);
442
 
        list_for_each_entry(err_drv, &cls->drivers, entry) {
443
 
                if (err_drv == drv)
444
 
                        break;
445
 
                if (err_drv->resume)
446
 
                        err_drv->resume(sysdev);
447
 
        }
448
 
 
449
 
        /* resume other sysdevs in current class */
450
 
        list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
451
 
                if (err_dev == sysdev)
452
 
                        break;
453
 
                pr_debug(" %s\n", kobject_name(&err_dev->kobj));
454
 
                __sysdev_resume(err_dev);
455
 
        }
456
 
 
457
 
        /* resume other classes */
458
 
        list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) {
459
 
                list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
460
 
                        pr_debug(" %s\n", kobject_name(&err_dev->kobj));
461
 
                        __sysdev_resume(err_dev);
462
 
                }
463
 
        }
464
 
        return ret;
465
 
}
466
 
EXPORT_SYMBOL_GPL(sysdev_suspend);
467
 
 
468
 
/**
469
 
 *      sysdev_resume - Bring system devices back to life.
470
 
 *
471
 
 *      Similar to sysdev_suspend(), but we iterate the list forwards
472
 
 *      to guarantee that parent devices are resumed before their children.
473
 
 *
474
 
 *      Note: Interrupts are disabled when called.
475
 
 */
476
 
int sysdev_resume(void)
477
 
{
478
 
        struct sysdev_class *cls;
479
 
 
480
 
        WARN_ONCE(!irqs_disabled(),
481
 
                "Interrupts enabled while resuming system devices\n");
482
 
 
483
 
        pr_debug("Resuming System Devices\n");
484
 
 
485
 
        list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
486
 
                struct sys_device *sysdev;
487
 
 
488
 
                pr_debug("Resuming type '%s':\n",
489
 
                         kobject_name(&cls->kset.kobj));
490
 
 
491
 
                list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
492
 
                        pr_debug(" %s\n", kobject_name(&sysdev->kobj));
493
 
 
494
 
                        __sysdev_resume(sysdev);
495
 
                }
496
 
        }
497
 
        return 0;
498
 
}
499
 
EXPORT_SYMBOL_GPL(sysdev_resume);
 
331
EXPORT_SYMBOL_GPL(sysdev_register);
 
332
EXPORT_SYMBOL_GPL(sysdev_unregister);
500
333
 
501
334
int __init system_bus_init(void)
502
335
{
506
339
        return 0;
507
340
}
508
341
 
509
 
EXPORT_SYMBOL_GPL(sysdev_register);
510
 
EXPORT_SYMBOL_GPL(sysdev_unregister);
511
 
 
512
342
#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
513
343
 
514
344
ssize_t sysdev_store_ulong(struct sys_device *sysdev,