aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2010-09-02 08:50:59 -0400
committerRusty Russell <rusty@rustcorp.com.au>2010-10-21 03:14:03 -0400
commitd22a69892bd8f29e3096f6f54c2c00d8aec2e796 (patch)
tree3deb620fc46810c15ab2d3b3cfb09d960666b40e /drivers
parent04950cdf071b6e5aa4794c93ad3e3ce8a1c4aa8c (diff)
virtio: console: Use cdev_alloc() instead of cdev_init()
This moves to using cdev on the heap instead of it being embedded in the ports struct. This helps individual refcounting and will allow us to properly remove cdev structs after hot-unplugs and close operations. Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/virtio_console.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 0c8f2aa3074a..8a9c140d19be 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -184,7 +184,7 @@ struct port {
184 struct console cons; 184 struct console cons;
185 185
186 /* Each port associates with a separate char device */ 186 /* Each port associates with a separate char device */
187 struct cdev cdev; 187 struct cdev *cdev;
188 struct device *dev; 188 struct device *dev;
189 189
190 /* A waitqueue for poll() or blocking read operations */ 190 /* A waitqueue for poll() or blocking read operations */
@@ -235,7 +235,7 @@ static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev,
235 235
236 spin_lock_irqsave(&portdev->ports_lock, flags); 236 spin_lock_irqsave(&portdev->ports_lock, flags);
237 list_for_each_entry(port, &portdev->ports, list) 237 list_for_each_entry(port, &portdev->ports, list)
238 if (port->cdev.dev == dev) 238 if (port->cdev->dev == dev)
239 goto out; 239 goto out;
240 port = NULL; 240 port = NULL;
241out: 241out:
@@ -1096,14 +1096,20 @@ static int add_port(struct ports_device *portdev, u32 id)
1096 port->in_vq = portdev->in_vqs[port->id]; 1096 port->in_vq = portdev->in_vqs[port->id];
1097 port->out_vq = portdev->out_vqs[port->id]; 1097 port->out_vq = portdev->out_vqs[port->id];
1098 1098
1099 cdev_init(&port->cdev, &port_fops); 1099 port->cdev = cdev_alloc();
1100 if (!port->cdev) {
1101 dev_err(&port->portdev->vdev->dev, "Error allocating cdev\n");
1102 err = -ENOMEM;
1103 goto free_port;
1104 }
1105 port->cdev->ops = &port_fops;
1100 1106
1101 devt = MKDEV(portdev->chr_major, id); 1107 devt = MKDEV(portdev->chr_major, id);
1102 err = cdev_add(&port->cdev, devt, 1); 1108 err = cdev_add(port->cdev, devt, 1);
1103 if (err < 0) { 1109 if (err < 0) {
1104 dev_err(&port->portdev->vdev->dev, 1110 dev_err(&port->portdev->vdev->dev,
1105 "Error %d adding cdev for port %u\n", err, id); 1111 "Error %d adding cdev for port %u\n", err, id);
1106 goto free_port; 1112 goto free_cdev;
1107 } 1113 }
1108 port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev, 1114 port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev,
1109 devt, port, "vport%up%u", 1115 devt, port, "vport%up%u",
@@ -1168,7 +1174,7 @@ free_inbufs:
1168free_device: 1174free_device:
1169 device_destroy(pdrvdata.class, port->dev->devt); 1175 device_destroy(pdrvdata.class, port->dev->devt);
1170free_cdev: 1176free_cdev:
1171 cdev_del(&port->cdev); 1177 cdev_del(port->cdev);
1172free_port: 1178free_port:
1173 kfree(port); 1179 kfree(port);
1174fail: 1180fail:
@@ -1212,7 +1218,7 @@ static void remove_port(struct port *port)
1212 } 1218 }
1213 sysfs_remove_group(&port->dev->kobj, &port_attribute_group); 1219 sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
1214 device_destroy(pdrvdata.class, port->dev->devt); 1220 device_destroy(pdrvdata.class, port->dev->devt);
1215 cdev_del(&port->cdev); 1221 cdev_del(port->cdev);
1216 1222
1217 /* Remove unused data this port might have received. */ 1223 /* Remove unused data this port might have received. */
1218 discard_port_data(port); 1224 discard_port_data(port);