aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/cio/device.c56
1 files changed, 12 insertions, 44 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 3b56f373da..03355902c5 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -290,16 +290,10 @@ int ccw_device_is_orphan(struct ccw_device *cdev)
290 return sch_is_pseudo_sch(to_subchannel(cdev->dev.parent)); 290 return sch_is_pseudo_sch(to_subchannel(cdev->dev.parent));
291} 291}
292 292
293static void ccw_device_unregister(struct work_struct *work) 293static void ccw_device_unregister(struct ccw_device *cdev)
294{ 294{
295 struct ccw_device_private *priv;
296 struct ccw_device *cdev;
297
298 priv = container_of(work, struct ccw_device_private, kick_work);
299 cdev = priv->cdev;
300 if (test_and_clear_bit(1, &cdev->private->registered)) 295 if (test_and_clear_bit(1, &cdev->private->registered))
301 device_unregister(&cdev->dev); 296 device_del(&cdev->dev);
302 put_device(&cdev->dev);
303} 297}
304 298
305static void 299static void
@@ -316,11 +310,8 @@ ccw_device_remove_disconnected(struct ccw_device *cdev)
316 spin_lock_irqsave(cdev->ccwlock, flags); 310 spin_lock_irqsave(cdev->ccwlock, flags);
317 cdev->private->state = DEV_STATE_NOT_OPER; 311 cdev->private->state = DEV_STATE_NOT_OPER;
318 spin_unlock_irqrestore(cdev->ccwlock, flags); 312 spin_unlock_irqrestore(cdev->ccwlock, flags);
319 if (get_device(&cdev->dev)) { 313 ccw_device_unregister(cdev);
320 PREPARE_WORK(&cdev->private->kick_work, 314 put_device(&cdev->dev);
321 ccw_device_unregister);
322 queue_work(ccw_device_work, &cdev->private->kick_work);
323 }
324 return ; 315 return ;
325 } 316 }
326 sch = to_subchannel(cdev->dev.parent); 317 sch = to_subchannel(cdev->dev.parent);
@@ -555,17 +546,10 @@ static struct attribute_group ccwdev_attr_group = {
555 .attrs = ccwdev_attrs, 546 .attrs = ccwdev_attrs,
556}; 547};
557 548
558static int 549struct attribute_group *ccwdev_attr_groups[] = {
559device_add_files (struct device *dev) 550 &ccwdev_attr_group,
560{ 551 NULL,
561 return sysfs_create_group(&dev->kobj, &ccwdev_attr_group); 552};
562}
563
564static void
565device_remove_files(struct device *dev)
566{
567 sysfs_remove_group(&dev->kobj, &ccwdev_attr_group);
568}
569 553
570/* this is a simple abstraction for device_register that sets the 554/* this is a simple abstraction for device_register that sets the
571 * correct bus type and adds the bus specific files */ 555 * correct bus type and adds the bus specific files */
@@ -580,10 +564,6 @@ static int ccw_device_register(struct ccw_device *cdev)
580 return ret; 564 return ret;
581 565
582 set_bit(1, &cdev->private->registered); 566 set_bit(1, &cdev->private->registered);
583 if ((ret = device_add_files(dev))) {
584 if (test_and_clear_bit(1, &cdev->private->registered))
585 device_del(dev);
586 }
587 return ret; 567 return ret;
588} 568}
589 569
@@ -655,10 +635,6 @@ ccw_device_add_changed(struct work_struct *work)
655 return; 635 return;
656 } 636 }
657 set_bit(1, &cdev->private->registered); 637 set_bit(1, &cdev->private->registered);
658 if (device_add_files(&cdev->dev)) {
659 if (test_and_clear_bit(1, &cdev->private->registered))
660 device_unregister(&cdev->dev);
661 }
662} 638}
663 639
664void ccw_device_do_unreg_rereg(struct work_struct *work) 640void ccw_device_do_unreg_rereg(struct work_struct *work)
@@ -671,9 +647,7 @@ void ccw_device_do_unreg_rereg(struct work_struct *work)
671 cdev = priv->cdev; 647 cdev = priv->cdev;
672 sch = to_subchannel(cdev->dev.parent); 648 sch = to_subchannel(cdev->dev.parent);
673 649
674 device_remove_files(&cdev->dev); 650 ccw_device_unregister(cdev);
675 if (test_and_clear_bit(1, &cdev->private->registered))
676 device_del(&cdev->dev);
677 PREPARE_WORK(&cdev->private->kick_work, 651 PREPARE_WORK(&cdev->private->kick_work,
678 ccw_device_add_changed); 652 ccw_device_add_changed);
679 queue_work(ccw_device_work, &cdev->private->kick_work); 653 queue_work(ccw_device_work, &cdev->private->kick_work);
@@ -712,6 +686,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch,
712 cdev->dev.parent = &sch->dev; 686 cdev->dev.parent = &sch->dev;
713 cdev->dev.release = ccw_device_release; 687 cdev->dev.release = ccw_device_release;
714 INIT_LIST_HEAD(&cdev->private->kick_work.entry); 688 INIT_LIST_HEAD(&cdev->private->kick_work.entry);
689 cdev->dev.groups = ccwdev_attr_groups;
715 /* Do first half of device_register. */ 690 /* Do first half of device_register. */
716 device_initialize(&cdev->dev); 691 device_initialize(&cdev->dev);
717 if (!get_device(&sch->dev)) { 692 if (!get_device(&sch->dev)) {
@@ -1141,15 +1116,8 @@ io_subchannel_remove (struct subchannel *sch)
1141 sch->dev.driver_data = NULL; 1116 sch->dev.driver_data = NULL;
1142 cdev->private->state = DEV_STATE_NOT_OPER; 1117 cdev->private->state = DEV_STATE_NOT_OPER;
1143 spin_unlock_irqrestore(cdev->ccwlock, flags); 1118 spin_unlock_irqrestore(cdev->ccwlock, flags);
1144 /* 1119 ccw_device_unregister(cdev);
1145 * Put unregistration on workqueue to avoid livelocks on the css bus 1120 put_device(&cdev->dev);
1146 * semaphore.
1147 */
1148 if (get_device(&cdev->dev)) {
1149 PREPARE_WORK(&cdev->private->kick_work,
1150 ccw_device_unregister);
1151 queue_work(ccw_device_work, &cdev->private->kick_work);
1152 }
1153 return 0; 1121 return 0;
1154} 1122}
1155 1123