aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/cio/device.c27
-rw-r--r--drivers/s390/cio/device.h2
-rw-r--r--drivers/s390/cio/device_fsm.c4
3 files changed, 10 insertions, 23 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 23d5752349b5..71b3b73e8ebe 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -681,35 +681,22 @@ get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css,
681 return dev ? to_ccwdev(dev) : NULL; 681 return dev ? to_ccwdev(dev) : NULL;
682} 682}
683 683
684static void 684void ccw_device_do_unbind_bind(struct work_struct *work)
685ccw_device_add_changed(struct work_struct *work)
686{
687 struct ccw_device_private *priv;
688 struct ccw_device *cdev;
689
690 priv = container_of(work, struct ccw_device_private, kick_work);
691 cdev = priv->cdev;
692 if (device_add(&cdev->dev)) {
693 put_device(&cdev->dev);
694 return;
695 }
696 set_bit(1, &cdev->private->registered);
697}
698
699void ccw_device_do_unreg_rereg(struct work_struct *work)
700{ 685{
701 struct ccw_device_private *priv; 686 struct ccw_device_private *priv;
702 struct ccw_device *cdev; 687 struct ccw_device *cdev;
703 struct subchannel *sch; 688 struct subchannel *sch;
689 int ret;
704 690
705 priv = container_of(work, struct ccw_device_private, kick_work); 691 priv = container_of(work, struct ccw_device_private, kick_work);
706 cdev = priv->cdev; 692 cdev = priv->cdev;
707 sch = to_subchannel(cdev->dev.parent); 693 sch = to_subchannel(cdev->dev.parent);
708 694
709 ccw_device_unregister(cdev); 695 if (test_bit(1, &cdev->private->registered)) {
710 PREPARE_WORK(&cdev->private->kick_work, 696 device_release_driver(&cdev->dev);
711 ccw_device_add_changed); 697 ret = device_attach(&cdev->dev);
712 queue_work(ccw_device_work, &cdev->private->kick_work); 698 WARN_ON(ret == -ENODEV);
699 }
713} 700}
714 701
715static void 702static void
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 0f2e63ea48de..85e01846ca65 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -80,7 +80,7 @@ void io_subchannel_init_config(struct subchannel *sch);
80 80
81int ccw_device_cancel_halt_clear(struct ccw_device *); 81int ccw_device_cancel_halt_clear(struct ccw_device *);
82 82
83void ccw_device_do_unreg_rereg(struct work_struct *); 83void ccw_device_do_unbind_bind(struct work_struct *);
84void ccw_device_move_to_orphanage(struct work_struct *); 84void ccw_device_move_to_orphanage(struct work_struct *);
85int ccw_device_is_orphan(struct ccw_device *); 85int ccw_device_is_orphan(struct ccw_device *);
86 86
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 8df5eaafc5ab..95f2f352cb9d 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
194 cdev->id.dev_type != cdev->private->senseid.dev_type || 194 cdev->id.dev_type != cdev->private->senseid.dev_type ||
195 cdev->id.dev_model != cdev->private->senseid.dev_model) { 195 cdev->id.dev_model != cdev->private->senseid.dev_model) {
196 PREPARE_WORK(&cdev->private->kick_work, 196 PREPARE_WORK(&cdev->private->kick_work,
197 ccw_device_do_unreg_rereg); 197 ccw_device_do_unbind_bind);
198 queue_work(ccw_device_work, &cdev->private->kick_work); 198 queue_work(ccw_device_work, &cdev->private->kick_work);
199 return 0; 199 return 0;
200 } 200 }
@@ -366,7 +366,7 @@ static void ccw_device_oper_notify(struct ccw_device *cdev)
366 } 366 }
367 /* Driver doesn't want device back. */ 367 /* Driver doesn't want device back. */
368 ccw_device_set_notoper(cdev); 368 ccw_device_set_notoper(cdev);
369 PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg); 369 PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
370 queue_work(ccw_device_work, &cdev->private->kick_work); 370 queue_work(ccw_device_work, &cdev->private->kick_work);
371} 371}
372 372