aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-04-13 07:03:03 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-04-17 08:07:32 -0400
commitafdfed0f86d192c9957996d58d51c06ff2b9cb44 (patch)
treef81c16aa5b6561e4988cdb4c78ea657c85f3f459 /drivers/s390/cio
parent863fc8492734822b95671780db803cd9a4b7d923 (diff)
s390/cio: get rid of static console device
Remove the static console ccw device (and friends) and use dynamic allocation for these structures. With this change the console device is treated (mostly) like any other ccw device and we can remove some special cases. Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/device.c73
1 files changed, 30 insertions, 43 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 25d04b7b5109..41a16785be29 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1087,19 +1087,12 @@ static int io_subchannel_probe(struct subchannel *sch)
1087 dev_set_uevent_suppress(&sch->dev, 0); 1087 dev_set_uevent_suppress(&sch->dev, 0);
1088 kobject_uevent(&sch->dev.kobj, KOBJ_ADD); 1088 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
1089 cdev = sch_get_cdev(sch); 1089 cdev = sch_get_cdev(sch);
1090 cdev->dev.groups = ccwdev_attr_groups; 1090 rc = ccw_device_register(cdev);
1091 device_initialize(&cdev->dev); 1091 if (rc) {
1092 cdev->private->flags.initialized = 1; 1092 /* Release online reference. */
1093 ccw_device_register(cdev); 1093 put_device(&cdev->dev);
1094 /* 1094 goto out_schedule;
1095 * Check if the device is already online. If it is 1095 }
1096 * the reference count needs to be corrected since we
1097 * didn't obtain a reference in ccw_device_set_online.
1098 */
1099 if (cdev->private->state != DEV_STATE_NOT_OPER &&
1100 cdev->private->state != DEV_STATE_OFFLINE &&
1101 cdev->private->state != DEV_STATE_BOXED)
1102 get_device(&cdev->dev);
1103 return 0; 1096 return 0;
1104 } 1097 }
1105 io_subchannel_init_fields(sch); 1098 io_subchannel_init_fields(sch);
@@ -1581,10 +1574,6 @@ out:
1581} 1574}
1582 1575
1583#ifdef CONFIG_CCW_CONSOLE 1576#ifdef CONFIG_CCW_CONSOLE
1584static struct ccw_device console_cdev;
1585static struct ccw_device_private console_private;
1586static int console_cdev_in_use;
1587
1588static int ccw_device_console_enable(struct ccw_device *cdev, 1577static int ccw_device_console_enable(struct ccw_device *cdev,
1589 struct subchannel *sch) 1578 struct subchannel *sch)
1590{ 1579{
@@ -1595,8 +1584,6 @@ static int ccw_device_console_enable(struct ccw_device *cdev,
1595 if (rc) 1584 if (rc)
1596 return rc; 1585 return rc;
1597 sch->driver = &io_subchannel_driver; 1586 sch->driver = &io_subchannel_driver;
1598 /* Initialize the ccw_device structure. */
1599 cdev->dev.parent= &sch->dev;
1600 sch_set_cdev(sch, cdev); 1587 sch_set_cdev(sch, cdev);
1601 io_subchannel_recog(cdev, sch); 1588 io_subchannel_recog(cdev, sch);
1602 /* Now wait for the async. recognition to come to an end. */ 1589 /* Now wait for the async. recognition to come to an end. */
@@ -1604,58 +1591,58 @@ static int ccw_device_console_enable(struct ccw_device *cdev,
1604 while (!dev_fsm_final_state(cdev)) 1591 while (!dev_fsm_final_state(cdev))
1605 ccw_device_wait_idle(cdev); 1592 ccw_device_wait_idle(cdev);
1606 1593
1607 rc = -EIO; 1594 /* Hold on to an extra reference while device is online. */
1608 if (cdev->private->state != DEV_STATE_OFFLINE) 1595 get_device(&cdev->dev);
1596 rc = ccw_device_online(cdev);
1597 if (rc)
1609 goto out_unlock; 1598 goto out_unlock;
1610 ccw_device_online(cdev); 1599
1611 while (!dev_fsm_final_state(cdev)) 1600 while (!dev_fsm_final_state(cdev))
1612 ccw_device_wait_idle(cdev); 1601 ccw_device_wait_idle(cdev);
1613 1602
1614 if (cdev->private->state != DEV_STATE_ONLINE) 1603 if (cdev->private->state == DEV_STATE_ONLINE)
1615 goto out_unlock; 1604 cdev->online = 1;
1616 rc = 0; 1605 else
1606 rc = -EIO;
1617out_unlock: 1607out_unlock:
1618 spin_unlock_irq(cdev->ccwlock); 1608 spin_unlock_irq(cdev->ccwlock);
1609 if (rc) /* Give up online reference since onlining failed. */
1610 put_device(&cdev->dev);
1619 return rc; 1611 return rc;
1620} 1612}
1621 1613
1622struct ccw_device * 1614struct ccw_device *ccw_device_probe_console(void)
1623ccw_device_probe_console(void)
1624{ 1615{
1625 struct io_subchannel_private *io_priv; 1616 struct io_subchannel_private *io_priv;
1617 struct ccw_device *cdev;
1626 struct subchannel *sch; 1618 struct subchannel *sch;
1627 int ret; 1619 int ret;
1628 1620
1629 if (xchg(&console_cdev_in_use, 1) != 0)
1630 return ERR_PTR(-EBUSY);
1631 sch = cio_probe_console(); 1621 sch = cio_probe_console();
1632 if (IS_ERR(sch)) { 1622 if (IS_ERR(sch))
1633 console_cdev_in_use = 0; 1623 return ERR_CAST(sch);
1634 return (void *) sch;
1635 }
1636 memset(&console_cdev, 0, sizeof(struct ccw_device));
1637 memset(&console_private, 0, sizeof(struct ccw_device_private));
1638 console_cdev.private = &console_private;
1639 console_private.cdev = &console_cdev;
1640 console_private.int_class = IRQIO_CIO;
1641 1624
1642 io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); 1625 io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA);
1643 if (!io_priv) { 1626 if (!io_priv) {
1644 put_device(&sch->dev); 1627 put_device(&sch->dev);
1645 return ERR_PTR(-ENOMEM); 1628 return ERR_PTR(-ENOMEM);
1646 } 1629 }
1630 cdev = io_subchannel_create_ccwdev(sch);
1631 if (IS_ERR(cdev)) {
1632 put_device(&sch->dev);
1633 kfree(io_priv);
1634 return cdev;
1635 }
1647 set_io_private(sch, io_priv); 1636 set_io_private(sch, io_priv);
1648 1637 ret = ccw_device_console_enable(cdev, sch);
1649 ret = ccw_device_console_enable(&console_cdev, sch);
1650 if (ret) { 1638 if (ret) {
1651 console_cdev_in_use = 0;
1652 set_io_private(sch, NULL); 1639 set_io_private(sch, NULL);
1653 put_device(&sch->dev); 1640 put_device(&sch->dev);
1641 put_device(&cdev->dev);
1654 kfree(io_priv); 1642 kfree(io_priv);
1655 return ERR_PTR(ret); 1643 return ERR_PTR(ret);
1656 } 1644 }
1657 console_cdev.online = 1; 1645 return cdev;
1658 return &console_cdev;
1659} 1646}
1660 1647
1661/** 1648/**