diff options
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r-- | drivers/s390/cio/device.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index d8d9b5b5cc56..dfef5e63cb7b 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -678,18 +678,11 @@ static const struct attribute_group *ccwdev_attr_groups[] = { | |||
678 | NULL, | 678 | NULL, |
679 | }; | 679 | }; |
680 | 680 | ||
681 | /* this is a simple abstraction for device_register that sets the | 681 | static int ccw_device_add(struct ccw_device *cdev) |
682 | * correct bus type and adds the bus specific files */ | ||
683 | static int ccw_device_register(struct ccw_device *cdev) | ||
684 | { | 682 | { |
685 | struct device *dev = &cdev->dev; | 683 | struct device *dev = &cdev->dev; |
686 | int ret; | ||
687 | 684 | ||
688 | dev->bus = &ccw_bus_type; | 685 | dev->bus = &ccw_bus_type; |
689 | ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid, | ||
690 | cdev->private->dev_id.devno); | ||
691 | if (ret) | ||
692 | return ret; | ||
693 | return device_add(dev); | 686 | return device_add(dev); |
694 | } | 687 | } |
695 | 688 | ||
@@ -764,22 +757,46 @@ static void ccw_device_todo(struct work_struct *work); | |||
764 | static int io_subchannel_initialize_dev(struct subchannel *sch, | 757 | static int io_subchannel_initialize_dev(struct subchannel *sch, |
765 | struct ccw_device *cdev) | 758 | struct ccw_device *cdev) |
766 | { | 759 | { |
767 | cdev->private->cdev = cdev; | 760 | struct ccw_device_private *priv = cdev->private; |
768 | cdev->private->int_class = IRQIO_CIO; | 761 | int ret; |
769 | atomic_set(&cdev->private->onoff, 0); | 762 | |
763 | priv->cdev = cdev; | ||
764 | priv->int_class = IRQIO_CIO; | ||
765 | priv->state = DEV_STATE_NOT_OPER; | ||
766 | priv->dev_id.devno = sch->schib.pmcw.dev; | ||
767 | priv->dev_id.ssid = sch->schid.ssid; | ||
768 | priv->schid = sch->schid; | ||
769 | |||
770 | INIT_WORK(&priv->todo_work, ccw_device_todo); | ||
771 | INIT_LIST_HEAD(&priv->cmb_list); | ||
772 | init_waitqueue_head(&priv->wait_q); | ||
773 | init_timer(&priv->timer); | ||
774 | |||
775 | atomic_set(&priv->onoff, 0); | ||
776 | cdev->ccwlock = sch->lock; | ||
770 | cdev->dev.parent = &sch->dev; | 777 | cdev->dev.parent = &sch->dev; |
771 | cdev->dev.release = ccw_device_release; | 778 | cdev->dev.release = ccw_device_release; |
772 | INIT_WORK(&cdev->private->todo_work, ccw_device_todo); | ||
773 | cdev->dev.groups = ccwdev_attr_groups; | 779 | cdev->dev.groups = ccwdev_attr_groups; |
774 | /* Do first half of device_register. */ | 780 | /* Do first half of device_register. */ |
775 | device_initialize(&cdev->dev); | 781 | device_initialize(&cdev->dev); |
782 | ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid, | ||
783 | cdev->private->dev_id.devno); | ||
784 | if (ret) | ||
785 | goto out_put; | ||
776 | if (!get_device(&sch->dev)) { | 786 | if (!get_device(&sch->dev)) { |
777 | /* Release reference from device_initialize(). */ | 787 | ret = -ENODEV; |
778 | put_device(&cdev->dev); | 788 | goto out_put; |
779 | return -ENODEV; | ||
780 | } | 789 | } |
781 | cdev->private->flags.initialized = 1; | 790 | priv->flags.initialized = 1; |
791 | spin_lock_irq(sch->lock); | ||
792 | sch_set_cdev(sch, cdev); | ||
793 | spin_unlock_irq(sch->lock); | ||
782 | return 0; | 794 | return 0; |
795 | |||
796 | out_put: | ||
797 | /* Release reference from device_initialize(). */ | ||
798 | put_device(&cdev->dev); | ||
799 | return ret; | ||
783 | } | 800 | } |
784 | 801 | ||
785 | static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) | 802 | static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) |
@@ -858,7 +875,7 @@ static void io_subchannel_register(struct ccw_device *cdev) | |||
858 | dev_set_uevent_suppress(&sch->dev, 0); | 875 | dev_set_uevent_suppress(&sch->dev, 0); |
859 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 876 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
860 | /* make it known to the system */ | 877 | /* make it known to the system */ |
861 | ret = ccw_device_register(cdev); | 878 | ret = ccw_device_add(cdev); |
862 | if (ret) { | 879 | if (ret) { |
863 | CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n", | 880 | CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n", |
864 | cdev->private->dev_id.ssid, | 881 | cdev->private->dev_id.ssid, |
@@ -923,26 +940,11 @@ io_subchannel_recog_done(struct ccw_device *cdev) | |||
923 | 940 | ||
924 | static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) | 941 | static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) |
925 | { | 942 | { |
926 | struct ccw_device_private *priv; | ||
927 | |||
928 | cdev->ccwlock = sch->lock; | ||
929 | |||
930 | /* Init private data. */ | ||
931 | priv = cdev->private; | ||
932 | priv->dev_id.devno = sch->schib.pmcw.dev; | ||
933 | priv->dev_id.ssid = sch->schid.ssid; | ||
934 | priv->schid = sch->schid; | ||
935 | priv->state = DEV_STATE_NOT_OPER; | ||
936 | INIT_LIST_HEAD(&priv->cmb_list); | ||
937 | init_waitqueue_head(&priv->wait_q); | ||
938 | init_timer(&priv->timer); | ||
939 | |||
940 | /* Increase counter of devices currently in recognition. */ | 943 | /* Increase counter of devices currently in recognition. */ |
941 | atomic_inc(&ccw_device_init_count); | 944 | atomic_inc(&ccw_device_init_count); |
942 | 945 | ||
943 | /* Start async. device sensing. */ | 946 | /* Start async. device sensing. */ |
944 | spin_lock_irq(sch->lock); | 947 | spin_lock_irq(sch->lock); |
945 | sch_set_cdev(sch, cdev); | ||
946 | ccw_device_recognition(cdev); | 948 | ccw_device_recognition(cdev); |
947 | spin_unlock_irq(sch->lock); | 949 | spin_unlock_irq(sch->lock); |
948 | } | 950 | } |
@@ -1083,7 +1085,7 @@ static int io_subchannel_probe(struct subchannel *sch) | |||
1083 | dev_set_uevent_suppress(&sch->dev, 0); | 1085 | dev_set_uevent_suppress(&sch->dev, 0); |
1084 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 1086 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
1085 | cdev = sch_get_cdev(sch); | 1087 | cdev = sch_get_cdev(sch); |
1086 | rc = ccw_device_register(cdev); | 1088 | rc = ccw_device_add(cdev); |
1087 | if (rc) { | 1089 | if (rc) { |
1088 | /* Release online reference. */ | 1090 | /* Release online reference. */ |
1089 | put_device(&cdev->dev); | 1091 | put_device(&cdev->dev); |
@@ -1597,7 +1599,6 @@ int __init ccw_device_enable_console(struct ccw_device *cdev) | |||
1597 | if (rc) | 1599 | if (rc) |
1598 | return rc; | 1600 | return rc; |
1599 | sch->driver = &io_subchannel_driver; | 1601 | sch->driver = &io_subchannel_driver; |
1600 | sch_set_cdev(sch, cdev); | ||
1601 | io_subchannel_recog(cdev, sch); | 1602 | io_subchannel_recog(cdev, sch); |
1602 | /* Now wait for the async. recognition to come to an end. */ | 1603 | /* Now wait for the async. recognition to come to an end. */ |
1603 | spin_lock_irq(cdev->ccwlock); | 1604 | spin_lock_irq(cdev->ccwlock); |
@@ -1639,6 +1640,7 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv) | |||
1639 | put_device(&sch->dev); | 1640 | put_device(&sch->dev); |
1640 | return ERR_PTR(-ENOMEM); | 1641 | return ERR_PTR(-ENOMEM); |
1641 | } | 1642 | } |
1643 | set_io_private(sch, io_priv); | ||
1642 | cdev = io_subchannel_create_ccwdev(sch); | 1644 | cdev = io_subchannel_create_ccwdev(sch); |
1643 | if (IS_ERR(cdev)) { | 1645 | if (IS_ERR(cdev)) { |
1644 | put_device(&sch->dev); | 1646 | put_device(&sch->dev); |
@@ -1646,7 +1648,6 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv) | |||
1646 | return cdev; | 1648 | return cdev; |
1647 | } | 1649 | } |
1648 | cdev->drv = drv; | 1650 | cdev->drv = drv; |
1649 | set_io_private(sch, io_priv); | ||
1650 | ccw_device_set_int_class(cdev); | 1651 | ccw_device_set_int_class(cdev); |
1651 | return cdev; | 1652 | return cdev; |
1652 | } | 1653 | } |