From acad9559f1054487292eb10d7bb81f256e9d8f2d Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 7 Jul 2005 17:56:24 -0700 Subject: [PATCH] hvc_console: Separate hvc_console and vio code 2 Remove all the vio device driver code from hvc_console.c This will allow us to separate hvsi, hvc, and allow hvc_console to be used without the ppc64 vio layer. Signed-off-by: Milton Miller Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hvc_vio.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 drivers/char/hvc_vio.c (limited to 'drivers/char/hvc_vio.c') diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c new file mode 100644 index 000000000000..d2928f90ab51 --- /dev/null +++ b/drivers/char/hvc_vio.c @@ -0,0 +1,125 @@ +/* + * vio driver interface to hvc_console.c + * + * This code was moved here to allow the remaing code to be reused as a + * generic polling mode with semi-reliable transport driver core to the + * console and tty subsystems. + * + * + * Copyright (C) 2001 Anton Blanchard , IBM + * Copyright (C) 2001 Paul Mackerras , IBM + * Copyright (C) 2004 Benjamin Herrenschmidt , IBM Corp. + * Copyright (C) 2004 IBM Corporation + * + * Additional Author(s): + * Ryan S. Arnold + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +char hvc_driver_name[] = "hvc_console"; + +static struct vio_device_id hvc_driver_table[] __devinitdata = { + {"serial", "hvterm1"}, + { NULL, } +}; +MODULE_DEVICE_TABLE(vio, hvc_driver_table); + +static int __devinit hvc_vio_probe(struct vio_dev *vdev, + const struct vio_device_id *id) +{ + struct hvc_struct *hp; + + /* probed with invalid parameters. */ + if (!vdev || !id) + return -EPERM; + + hp = hvc_alloc(vdev->unit_address, vdev->irq); + if (IS_ERR(hp)) + return PTR_ERR(hp); + dev_set_drvdata(&vdev->dev, hp); + + return 0; +} + +static int __devexit hvc_vio_remove(struct vio_dev *vdev) +{ + struct hvc_struct *hp = dev_get_drvdata(&vdev->dev); + + return hvc_remove(hp); +} + +static struct vio_driver hvc_vio_driver = { + .name = hvc_driver_name, + .id_table = hvc_driver_table, + .probe = hvc_vio_probe, + .remove = hvc_vio_remove, + .driver = { + .owner = THIS_MODULE, + } +}; + +static int hvc_vio_init(void) +{ + int rc; + + /* Register as a vio device to receive callbacks */ + rc = vio_register_driver(&hvc_vio_driver); + + return rc; +} +module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */ + +static void hvc_vio_exit(void) +{ + vio_unregister_driver(&hvc_vio_driver); +} +module_exit(hvc_vio_exit); + +/* the device tree order defines our numbering */ +static int hvc_find_vtys(void) +{ + struct device_node *vty; + int num_found = 0; + + for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL; + vty = of_find_node_by_name(vty, "vty")) { + uint32_t *vtermno; + + /* We have statically defined space for only a certain number + * of console adapters. + */ + if (num_found >= MAX_NR_HVC_CONSOLES) + break; + + vtermno = (uint32_t *)get_property(vty, "reg", NULL); + if (!vtermno) + continue; + + if (device_is_compatible(vty, "hvterm1")) { + hvc_instantiate(*vtermno, num_found); + ++num_found; + } + } + + return num_found; +} +console_initcall(hvc_find_vtys); -- cgit v1.2.2 From 030ffad23fb28fc29608a3bc21f0c3b88bf28592 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 7 Jul 2005 17:56:25 -0700 Subject: [PATCH] hvc_console: Register ops when setting up hvc_console When registering the hvc console port, register a list of ops (read and write) to go with it, instead of calling fixed function names. This allows different ports to encode the data differently. Signed-off-by: Milton Miller Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hvc_vio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/char/hvc_vio.c') diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index d2928f90ab51..430a2c284ad2 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -43,6 +43,11 @@ static struct vio_device_id hvc_driver_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(vio, hvc_driver_table); +static struct hv_ops hvc_get_put_ops = { + .get_chars = hvc_get_chars, + .put_chars = hvc_put_chars, +}; + static int __devinit hvc_vio_probe(struct vio_dev *vdev, const struct vio_device_id *id) { @@ -52,7 +57,7 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev, if (!vdev || !id) return -EPERM; - hp = hvc_alloc(vdev->unit_address, vdev->irq); + hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops); if (IS_ERR(hp)) return PTR_ERR(hp); dev_set_drvdata(&vdev->dev, hp); @@ -115,7 +120,7 @@ static int hvc_find_vtys(void) continue; if (device_is_compatible(vty, "hvterm1")) { - hvc_instantiate(*vtermno, num_found); + hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops); ++num_found; } } -- cgit v1.2.2 From 70b234a40107596a713e9981c643f2717e31463f Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 7 Jul 2005 17:56:26 -0700 Subject: [PATCH] hvc_console: Separate the NUL character filtering from get_hvc_chars Separate the NUL character filtering from get_hvc_chars. Signed-off-by: Milton Miller Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hvc_vio.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'drivers/char/hvc_vio.c') diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index 430a2c284ad2..60bb9152b832 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -43,8 +43,30 @@ static struct vio_device_id hvc_driver_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(vio, hvc_driver_table); +static int filtered_get_chars(uint32_t vtermno, char *buf, int count) +{ + unsigned long got; + int i; + + got = hvc_get_chars(vtermno, buf, count); + + /* + * Work around a HV bug where it gives us a null + * after every \r. -- paulus + */ + for (i = 1; i < got; ++i) { + if (buf[i] == 0 && buf[i-1] == '\r') { + --got; + if (i < got) + memmove(&buf[i], &buf[i+1], + got - i); + } + } + return got; +} + static struct hv_ops hvc_get_put_ops = { - .get_chars = hvc_get_chars, + .get_chars = filtered_get_chars, .put_chars = hvc_put_chars, }; -- cgit v1.2.2