.. | .. |
---|
485 | 485 | gdrv->shutdown(gdev); |
---|
486 | 486 | } |
---|
487 | 487 | |
---|
488 | | -static int ccwgroup_pm_prepare(struct device *dev) |
---|
489 | | -{ |
---|
490 | | - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
---|
491 | | - struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); |
---|
492 | | - |
---|
493 | | - /* Fail while device is being set online/offline. */ |
---|
494 | | - if (atomic_read(&gdev->onoff)) |
---|
495 | | - return -EAGAIN; |
---|
496 | | - |
---|
497 | | - if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) |
---|
498 | | - return 0; |
---|
499 | | - |
---|
500 | | - return gdrv->prepare ? gdrv->prepare(gdev) : 0; |
---|
501 | | -} |
---|
502 | | - |
---|
503 | | -static void ccwgroup_pm_complete(struct device *dev) |
---|
504 | | -{ |
---|
505 | | - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
---|
506 | | - struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); |
---|
507 | | - |
---|
508 | | - if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) |
---|
509 | | - return; |
---|
510 | | - |
---|
511 | | - if (gdrv->complete) |
---|
512 | | - gdrv->complete(gdev); |
---|
513 | | -} |
---|
514 | | - |
---|
515 | | -static int ccwgroup_pm_freeze(struct device *dev) |
---|
516 | | -{ |
---|
517 | | - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
---|
518 | | - struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); |
---|
519 | | - |
---|
520 | | - if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) |
---|
521 | | - return 0; |
---|
522 | | - |
---|
523 | | - return gdrv->freeze ? gdrv->freeze(gdev) : 0; |
---|
524 | | -} |
---|
525 | | - |
---|
526 | | -static int ccwgroup_pm_thaw(struct device *dev) |
---|
527 | | -{ |
---|
528 | | - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
---|
529 | | - struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); |
---|
530 | | - |
---|
531 | | - if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) |
---|
532 | | - return 0; |
---|
533 | | - |
---|
534 | | - return gdrv->thaw ? gdrv->thaw(gdev) : 0; |
---|
535 | | -} |
---|
536 | | - |
---|
537 | | -static int ccwgroup_pm_restore(struct device *dev) |
---|
538 | | -{ |
---|
539 | | - struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
---|
540 | | - struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); |
---|
541 | | - |
---|
542 | | - if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) |
---|
543 | | - return 0; |
---|
544 | | - |
---|
545 | | - return gdrv->restore ? gdrv->restore(gdev) : 0; |
---|
546 | | -} |
---|
547 | | - |
---|
548 | | -static const struct dev_pm_ops ccwgroup_pm_ops = { |
---|
549 | | - .prepare = ccwgroup_pm_prepare, |
---|
550 | | - .complete = ccwgroup_pm_complete, |
---|
551 | | - .freeze = ccwgroup_pm_freeze, |
---|
552 | | - .thaw = ccwgroup_pm_thaw, |
---|
553 | | - .restore = ccwgroup_pm_restore, |
---|
554 | | -}; |
---|
555 | | - |
---|
556 | 488 | static struct bus_type ccwgroup_bus_type = { |
---|
557 | 489 | .name = "ccwgroup", |
---|
558 | 490 | .remove = ccwgroup_remove, |
---|
559 | 491 | .shutdown = ccwgroup_shutdown, |
---|
560 | | - .pm = &ccwgroup_pm_ops, |
---|
561 | 492 | }; |
---|
562 | 493 | |
---|
563 | 494 | bool dev_is_ccwgroup(struct device *dev) |
---|
.. | .. |
---|
581 | 512 | } |
---|
582 | 513 | EXPORT_SYMBOL(ccwgroup_driver_register); |
---|
583 | 514 | |
---|
584 | | -static int __ccwgroup_match_all(struct device *dev, void *data) |
---|
585 | | -{ |
---|
586 | | - return 1; |
---|
587 | | -} |
---|
588 | | - |
---|
589 | 515 | /** |
---|
590 | 516 | * ccwgroup_driver_unregister() - deregister a ccw group driver |
---|
591 | 517 | * @cdriver: driver to be deregistered |
---|
.. | .. |
---|
597 | 523 | struct device *dev; |
---|
598 | 524 | |
---|
599 | 525 | /* We don't want ccwgroup devices to live longer than their driver. */ |
---|
600 | | - while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, |
---|
601 | | - __ccwgroup_match_all))) { |
---|
| 526 | + while ((dev = driver_find_next_device(&cdriver->driver, NULL))) { |
---|
602 | 527 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
---|
603 | 528 | |
---|
604 | 529 | ccwgroup_ungroup(gdev); |
---|
.. | .. |
---|
609 | 534 | EXPORT_SYMBOL(ccwgroup_driver_unregister); |
---|
610 | 535 | |
---|
611 | 536 | /** |
---|
| 537 | + * get_ccwgroupdev_by_busid() - obtain device from a bus id |
---|
| 538 | + * @gdrv: driver the device is owned by |
---|
| 539 | + * @bus_id: bus id of the device to be searched |
---|
| 540 | + * |
---|
| 541 | + * This function searches all devices owned by @gdrv for a device with a bus |
---|
| 542 | + * id matching @bus_id. |
---|
| 543 | + * Returns: |
---|
| 544 | + * If a match is found, its reference count of the found device is increased |
---|
| 545 | + * and it is returned; else %NULL is returned. |
---|
| 546 | + */ |
---|
| 547 | +struct ccwgroup_device *get_ccwgroupdev_by_busid(struct ccwgroup_driver *gdrv, |
---|
| 548 | + char *bus_id) |
---|
| 549 | +{ |
---|
| 550 | + struct device *dev; |
---|
| 551 | + |
---|
| 552 | + dev = driver_find_device_by_name(&gdrv->driver, bus_id); |
---|
| 553 | + |
---|
| 554 | + return dev ? to_ccwgroupdev(dev) : NULL; |
---|
| 555 | +} |
---|
| 556 | +EXPORT_SYMBOL_GPL(get_ccwgroupdev_by_busid); |
---|
| 557 | + |
---|
| 558 | +/** |
---|
612 | 559 | * ccwgroup_probe_ccwdev() - probe function for slave devices |
---|
613 | 560 | * @cdev: ccw device to be probed |
---|
614 | 561 | * |
---|