aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-08-07 15:48:06 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-13 19:53:14 -0400
commit27bf7c43a19c66bdc96ee3ee5a67e3bc2d601736 (patch)
treeae604e7027fa7631c4f2601ca7e0406f41e1c7a1 /drivers/tty/hvc
parent97d150898592be8d5381ebc8d435526df38a2791 (diff)
TTY: hvcs, add tty install
This has two outcomes: * we give the TTY layer a tty_port * we do not find the info structure every time open is called on that tty >From now on, we only increase the reference count in ->install (and decrease in ->cleanup). Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: linuxppc-dev@lists.ozlabs.org Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/hvcs.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 6f5c3be0f495..cab5c7adf8e8 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -1102,11 +1102,7 @@ static struct hvcs_struct *hvcs_get_by_index(int index)
1102 return NULL; 1102 return NULL;
1103} 1103}
1104 1104
1105/* 1105static int hvcs_install(struct tty_driver *driver, struct tty_struct *tty)
1106 * This is invoked via the tty_open interface when a user app connects to the
1107 * /dev node.
1108 */
1109static int hvcs_open(struct tty_struct *tty, struct file *filp)
1110{ 1106{
1111 struct hvcs_struct *hvcsd; 1107 struct hvcs_struct *hvcsd;
1112 struct vio_dev *vdev; 1108 struct vio_dev *vdev;
@@ -1114,9 +1110,6 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
1114 unsigned int irq; 1110 unsigned int irq;
1115 int retval; 1111 int retval;
1116 1112
1117 if (tty->driver_data)
1118 goto fast_open;
1119
1120 /* 1113 /*
1121 * Is there a vty-server that shares the same index? 1114 * Is there a vty-server that shares the same index?
1122 * This function increments the kref index. 1115 * This function increments the kref index.
@@ -1139,7 +1132,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
1139 } 1132 }
1140 } 1133 }
1141 1134
1142 hvcsd->port.count = 1; 1135 hvcsd->port.count = 0;
1143 hvcsd->port.tty = tty; 1136 hvcsd->port.tty = tty;
1144 tty->driver_data = hvcsd; 1137 tty->driver_data = hvcsd;
1145 1138
@@ -1166,28 +1159,42 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
1166 goto err_put; 1159 goto err_put;
1167 } 1160 }
1168 1161
1169 goto open_success; 1162 retval = tty_port_install(&hvcsd->port, driver, tty);
1163 if (retval)
1164 goto err_irq;
1170 1165
1171fast_open: 1166 return 0;
1172 hvcsd = tty->driver_data; 1167err_irq:
1168 spin_lock_irqsave(&hvcsd->lock, flags);
1169 vio_disable_interrupts(hvcsd->vdev);
1170 spin_unlock_irqrestore(&hvcsd->lock, flags);
1171 free_irq(irq, hvcsd);
1172err_put:
1173 tty_port_put(&hvcsd->port);
1174
1175 return retval;
1176}
1177
1178/*
1179 * This is invoked via the tty_open interface when a user app connects to the
1180 * /dev node.
1181 */
1182static int hvcs_open(struct tty_struct *tty, struct file *filp)
1183{
1184 struct hvcs_struct *hvcsd = tty->driver_data;
1185 unsigned long flags;
1173 1186
1174 spin_lock_irqsave(&hvcsd->lock, flags); 1187 spin_lock_irqsave(&hvcsd->lock, flags);
1175 tty_port_get(&hvcsd->port);
1176 hvcsd->port.count++; 1188 hvcsd->port.count++;
1177 hvcsd->todo_mask |= HVCS_SCHED_READ; 1189 hvcsd->todo_mask |= HVCS_SCHED_READ;
1178 spin_unlock_irqrestore(&hvcsd->lock, flags); 1190 spin_unlock_irqrestore(&hvcsd->lock, flags);
1179 1191
1180open_success:
1181 hvcs_kick(); 1192 hvcs_kick();
1182 1193
1183 printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n", 1194 printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n",
1184 hvcsd->vdev->unit_address ); 1195 hvcsd->vdev->unit_address );
1185 1196
1186 return 0; 1197 return 0;
1187err_put:
1188 tty_port_put(&hvcsd->port);
1189
1190 return retval;
1191} 1198}
1192 1199
1193static void hvcs_close(struct tty_struct *tty, struct file *filp) 1200static void hvcs_close(struct tty_struct *tty, struct file *filp)
@@ -1238,7 +1245,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
1238 tty->driver_data = NULL; 1245 tty->driver_data = NULL;
1239 1246
1240 free_irq(irq, hvcsd); 1247 free_irq(irq, hvcsd);
1241 tty_port_put(&hvcsd->port);
1242 return; 1248 return;
1243 } else if (hvcsd->port.count < 0) { 1249 } else if (hvcsd->port.count < 0) {
1244 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" 1250 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
@@ -1247,6 +1253,12 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
1247 } 1253 }
1248 1254
1249 spin_unlock_irqrestore(&hvcsd->lock, flags); 1255 spin_unlock_irqrestore(&hvcsd->lock, flags);
1256}
1257
1258static void hvcs_cleanup(struct tty_struct * tty)
1259{
1260 struct hvcs_struct *hvcsd = tty->driver_data;
1261
1250 tty_port_put(&hvcsd->port); 1262 tty_port_put(&hvcsd->port);
1251} 1263}
1252 1264
@@ -1433,8 +1445,10 @@ static int hvcs_chars_in_buffer(struct tty_struct *tty)
1433} 1445}
1434 1446
1435static const struct tty_operations hvcs_ops = { 1447static const struct tty_operations hvcs_ops = {
1448 .install = hvcs_install,
1436 .open = hvcs_open, 1449 .open = hvcs_open,
1437 .close = hvcs_close, 1450 .close = hvcs_close,
1451 .cleanup = hvcs_cleanup,
1438 .hangup = hvcs_hangup, 1452 .hangup = hvcs_hangup,
1439 .write = hvcs_write, 1453 .write = hvcs_write,
1440 .write_room = hvcs_write_room, 1454 .write_room = hvcs_write_room,