Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: powerpc: remove hvc_iseries

The PowerPC legacy iSeries platform is being removed, so this code is no
longer needed.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Stephen Rothwell and committed by
Benjamin Herrenschmidt
b6680891 7834799a

-610
-10
drivers/tty/hvc/Kconfig
··· 24 24 depends on HVC_CONSOLE 25 25 default n 26 26 27 - config HVC_ISERIES 28 - bool "iSeries Hypervisor Virtual Console support" 29 - depends on PPC_ISERIES 30 - default y 31 - select HVC_DRIVER 32 - select HVC_IRQ 33 - select VIOPATH 34 - help 35 - iSeries machines support a hypervisor virtual console. 36 - 37 27 config HVC_OPAL 38 28 bool "OPAL Console support" 39 29 depends on PPC_POWERNV
-1
drivers/tty/hvc/Makefile
··· 1 1 obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi_lib.o 2 2 obj-$(CONFIG_HVC_OPAL) += hvc_opal.o hvsi_lib.o 3 3 obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o 4 - obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o 5 4 obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o 6 5 obj-$(CONFIG_HVC_TILE) += hvc_tile.o 7 6 obj-$(CONFIG_HVC_DCC) += hvc_dcc.o
-599
drivers/tty/hvc/hvc_iseries.c
··· 1 - /* 2 - * iSeries vio driver interface to hvc_console.c 3 - * 4 - * This code is based heavily on hvc_vio.c and viocons.c 5 - * 6 - * Copyright (C) 2006 Stephen Rothwell, IBM Corporation 7 - * 8 - * This program is free software; you can redistribute it and/or modify 9 - * it under the terms of the GNU General Public License as published by 10 - * the Free Software Foundation; either version 2 of the License, or 11 - * (at your option) any later version. 12 - * 13 - * This program is distributed in the hope that it will be useful, 14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - * GNU General Public License for more details. 17 - * 18 - * You should have received a copy of the GNU General Public License 19 - * along with this program; if not, write to the Free Software 20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 - */ 22 - #include <stdarg.h> 23 - #include <linux/types.h> 24 - #include <linux/init.h> 25 - #include <linux/kernel.h> 26 - #include <linux/module.h> 27 - #include <linux/spinlock.h> 28 - #include <linux/console.h> 29 - 30 - #include <asm/hvconsole.h> 31 - #include <asm/vio.h> 32 - #include <asm/prom.h> 33 - #include <asm/firmware.h> 34 - #include <asm/iseries/vio.h> 35 - #include <asm/iseries/hv_call.h> 36 - #include <asm/iseries/hv_lp_config.h> 37 - #include <asm/iseries/hv_lp_event.h> 38 - 39 - #include "hvc_console.h" 40 - 41 - #define VTTY_PORTS 10 42 - 43 - static DEFINE_SPINLOCK(consolelock); 44 - static DEFINE_SPINLOCK(consoleloglock); 45 - 46 - static const char hvc_driver_name[] = "hvc_console"; 47 - 48 - #define IN_BUF_SIZE 200 49 - 50 - /* 51 - * Our port information. 52 - */ 53 - static struct port_info { 54 - HvLpIndex lp; 55 - u64 seq; /* sequence number of last HV send */ 56 - u64 ack; /* last ack from HV */ 57 - struct hvc_struct *hp; 58 - int in_start; 59 - int in_end; 60 - unsigned char in_buf[IN_BUF_SIZE]; 61 - } port_info[VTTY_PORTS] = { 62 - [ 0 ... VTTY_PORTS - 1 ] = { 63 - .lp = HvLpIndexInvalid 64 - } 65 - }; 66 - 67 - #define viochar_is_console(pi) ((pi) == &port_info[0]) 68 - 69 - static struct vio_device_id hvc_driver_table[] __devinitdata = { 70 - {"serial", "IBM,iSeries-vty"}, 71 - { "", "" } 72 - }; 73 - MODULE_DEVICE_TABLE(vio, hvc_driver_table); 74 - 75 - static void hvlog(char *fmt, ...) 76 - { 77 - int i; 78 - unsigned long flags; 79 - va_list args; 80 - static char buf[256]; 81 - 82 - spin_lock_irqsave(&consoleloglock, flags); 83 - va_start(args, fmt); 84 - i = vscnprintf(buf, sizeof(buf) - 1, fmt, args); 85 - va_end(args); 86 - buf[i++] = '\r'; 87 - HvCall_writeLogBuffer(buf, i); 88 - spin_unlock_irqrestore(&consoleloglock, flags); 89 - } 90 - 91 - /* 92 - * Initialize the common fields in a charLpEvent 93 - */ 94 - static void init_data_event(struct viocharlpevent *viochar, HvLpIndex lp) 95 - { 96 - struct HvLpEvent *hev = &viochar->event; 97 - 98 - memset(viochar, 0, sizeof(struct viocharlpevent)); 99 - 100 - hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK | 101 - HV_LP_EVENT_INT; 102 - hev->xType = HvLpEvent_Type_VirtualIo; 103 - hev->xSubtype = viomajorsubtype_chario | viochardata; 104 - hev->xSourceLp = HvLpConfig_getLpIndex(); 105 - hev->xTargetLp = lp; 106 - hev->xSizeMinus1 = sizeof(struct viocharlpevent); 107 - hev->xSourceInstanceId = viopath_sourceinst(lp); 108 - hev->xTargetInstanceId = viopath_targetinst(lp); 109 - } 110 - 111 - static int get_chars(uint32_t vtermno, char *buf, int count) 112 - { 113 - struct port_info *pi; 114 - int n = 0; 115 - unsigned long flags; 116 - 117 - if (vtermno >= VTTY_PORTS) 118 - return -EINVAL; 119 - if (count == 0) 120 - return 0; 121 - 122 - pi = &port_info[vtermno]; 123 - spin_lock_irqsave(&consolelock, flags); 124 - 125 - if (pi->in_end == 0) 126 - goto done; 127 - 128 - n = pi->in_end - pi->in_start; 129 - if (n > count) 130 - n = count; 131 - memcpy(buf, &pi->in_buf[pi->in_start], n); 132 - pi->in_start += n; 133 - if (pi->in_start == pi->in_end) { 134 - pi->in_start = 0; 135 - pi->in_end = 0; 136 - } 137 - done: 138 - spin_unlock_irqrestore(&consolelock, flags); 139 - return n; 140 - } 141 - 142 - static int put_chars(uint32_t vtermno, const char *buf, int count) 143 - { 144 - struct viocharlpevent *viochar; 145 - struct port_info *pi; 146 - HvLpEvent_Rc hvrc; 147 - unsigned long flags; 148 - int sent = 0; 149 - 150 - if (vtermno >= VTTY_PORTS) 151 - return -EINVAL; 152 - 153 - pi = &port_info[vtermno]; 154 - 155 - spin_lock_irqsave(&consolelock, flags); 156 - 157 - if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) { 158 - HvCall_writeLogBuffer(buf, count); 159 - sent = count; 160 - goto done; 161 - } 162 - 163 - viochar = vio_get_event_buffer(viomajorsubtype_chario); 164 - if (viochar == NULL) { 165 - hvlog("\n\rviocons: Can't get viochar buffer."); 166 - goto done; 167 - } 168 - 169 - while ((count > 0) && ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) { 170 - int len; 171 - 172 - len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count; 173 - 174 - if (viochar_is_console(pi)) 175 - HvCall_writeLogBuffer(buf, len); 176 - 177 - init_data_event(viochar, pi->lp); 178 - 179 - viochar->len = len; 180 - viochar->event.xCorrelationToken = pi->seq++; 181 - viochar->event.xSizeMinus1 = 182 - offsetof(struct viocharlpevent, data) + len; 183 - 184 - memcpy(viochar->data, buf, len); 185 - 186 - hvrc = HvCallEvent_signalLpEvent(&viochar->event); 187 - if (hvrc) 188 - hvlog("\n\rerror sending event! return code %d\n\r", 189 - (int)hvrc); 190 - sent += len; 191 - count -= len; 192 - buf += len; 193 - } 194 - 195 - vio_free_event_buffer(viomajorsubtype_chario, viochar); 196 - done: 197 - spin_unlock_irqrestore(&consolelock, flags); 198 - return sent; 199 - } 200 - 201 - static const struct hv_ops hvc_get_put_ops = { 202 - .get_chars = get_chars, 203 - .put_chars = put_chars, 204 - .notifier_add = notifier_add_irq, 205 - .notifier_del = notifier_del_irq, 206 - .notifier_hangup = notifier_hangup_irq, 207 - }; 208 - 209 - static int __devinit hvc_vio_probe(struct vio_dev *vdev, 210 - const struct vio_device_id *id) 211 - { 212 - struct hvc_struct *hp; 213 - struct port_info *pi; 214 - 215 - /* probed with invalid parameters. */ 216 - if (!vdev || !id) 217 - return -EPERM; 218 - 219 - if (vdev->unit_address >= VTTY_PORTS) 220 - return -ENODEV; 221 - 222 - pi = &port_info[vdev->unit_address]; 223 - 224 - hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops, 225 - VIOCHAR_MAX_DATA); 226 - if (IS_ERR(hp)) 227 - return PTR_ERR(hp); 228 - pi->hp = hp; 229 - dev_set_drvdata(&vdev->dev, pi); 230 - 231 - return 0; 232 - } 233 - 234 - static int __devexit hvc_vio_remove(struct vio_dev *vdev) 235 - { 236 - struct port_info *pi = dev_get_drvdata(&vdev->dev); 237 - struct hvc_struct *hp = pi->hp; 238 - 239 - return hvc_remove(hp); 240 - } 241 - 242 - static struct vio_driver hvc_vio_driver = { 243 - .id_table = hvc_driver_table, 244 - .probe = hvc_vio_probe, 245 - .remove = __devexit_p(hvc_vio_remove), 246 - .driver = { 247 - .name = hvc_driver_name, 248 - .owner = THIS_MODULE, 249 - } 250 - }; 251 - 252 - static void hvc_open_event(struct HvLpEvent *event) 253 - { 254 - unsigned long flags; 255 - struct viocharlpevent *cevent = (struct viocharlpevent *)event; 256 - u8 port = cevent->virtual_device; 257 - struct port_info *pi; 258 - int reject = 0; 259 - 260 - if (hvlpevent_is_ack(event)) { 261 - if (port >= VTTY_PORTS) 262 - return; 263 - 264 - spin_lock_irqsave(&consolelock, flags); 265 - 266 - pi = &port_info[port]; 267 - if (event->xRc == HvLpEvent_Rc_Good) { 268 - pi->seq = pi->ack = 0; 269 - /* 270 - * This line allows connections from the primary 271 - * partition but once one is connected from the 272 - * primary partition nothing short of a reboot 273 - * of linux will allow access from the hosting 274 - * partition again without a required iSeries fix. 275 - */ 276 - pi->lp = event->xTargetLp; 277 - } 278 - 279 - spin_unlock_irqrestore(&consolelock, flags); 280 - if (event->xRc != HvLpEvent_Rc_Good) 281 - printk(KERN_WARNING 282 - "hvc: handle_open_event: event->xRc == (%d).\n", 283 - event->xRc); 284 - 285 - if (event->xCorrelationToken != 0) { 286 - atomic_t *aptr= (atomic_t *)event->xCorrelationToken; 287 - atomic_set(aptr, 1); 288 - } else 289 - printk(KERN_WARNING 290 - "hvc: weird...got open ack without atomic\n"); 291 - return; 292 - } 293 - 294 - /* This had better require an ack, otherwise complain */ 295 - if (!hvlpevent_need_ack(event)) { 296 - printk(KERN_WARNING "hvc: viocharopen without ack bit!\n"); 297 - return; 298 - } 299 - 300 - spin_lock_irqsave(&consolelock, flags); 301 - 302 - /* Make sure this is a good virtual tty */ 303 - if (port >= VTTY_PORTS) { 304 - event->xRc = HvLpEvent_Rc_SubtypeError; 305 - cevent->subtype_result_code = viorc_openRejected; 306 - /* 307 - * Flag state here since we can't printk while holding 308 - * the consolelock spinlock. 309 - */ 310 - reject = 1; 311 - } else { 312 - pi = &port_info[port]; 313 - if ((pi->lp != HvLpIndexInvalid) && 314 - (pi->lp != event->xSourceLp)) { 315 - /* 316 - * If this is tty is already connected to a different 317 - * partition, fail. 318 - */ 319 - event->xRc = HvLpEvent_Rc_SubtypeError; 320 - cevent->subtype_result_code = viorc_openRejected; 321 - reject = 2; 322 - } else { 323 - pi->lp = event->xSourceLp; 324 - event->xRc = HvLpEvent_Rc_Good; 325 - cevent->subtype_result_code = viorc_good; 326 - pi->seq = pi->ack = 0; 327 - } 328 - } 329 - 330 - spin_unlock_irqrestore(&consolelock, flags); 331 - 332 - if (reject == 1) 333 - printk(KERN_WARNING "hvc: open rejected: bad virtual tty.\n"); 334 - else if (reject == 2) 335 - printk(KERN_WARNING "hvc: open rejected: console in exclusive " 336 - "use by another partition.\n"); 337 - 338 - /* Return the acknowledgement */ 339 - HvCallEvent_ackLpEvent(event); 340 - } 341 - 342 - /* 343 - * Handle a close charLpEvent. This should ONLY be an Interrupt because the 344 - * virtual console should never actually issue a close event to the hypervisor 345 - * because the virtual console never goes away. A close event coming from the 346 - * hypervisor simply means that there are no client consoles connected to the 347 - * virtual console. 348 - */ 349 - static void hvc_close_event(struct HvLpEvent *event) 350 - { 351 - unsigned long flags; 352 - struct viocharlpevent *cevent = (struct viocharlpevent *)event; 353 - u8 port = cevent->virtual_device; 354 - 355 - if (!hvlpevent_is_int(event)) { 356 - printk(KERN_WARNING 357 - "hvc: got unexpected close acknowledgement\n"); 358 - return; 359 - } 360 - 361 - if (port >= VTTY_PORTS) { 362 - printk(KERN_WARNING 363 - "hvc: close message from invalid virtual device.\n"); 364 - return; 365 - } 366 - 367 - /* For closes, just mark the console partition invalid */ 368 - spin_lock_irqsave(&consolelock, flags); 369 - 370 - if (port_info[port].lp == event->xSourceLp) 371 - port_info[port].lp = HvLpIndexInvalid; 372 - 373 - spin_unlock_irqrestore(&consolelock, flags); 374 - } 375 - 376 - static void hvc_data_event(struct HvLpEvent *event) 377 - { 378 - unsigned long flags; 379 - struct viocharlpevent *cevent = (struct viocharlpevent *)event; 380 - struct port_info *pi; 381 - int n; 382 - u8 port = cevent->virtual_device; 383 - 384 - if (port >= VTTY_PORTS) { 385 - printk(KERN_WARNING "hvc: data on invalid virtual device %d\n", 386 - port); 387 - return; 388 - } 389 - if (cevent->len == 0) 390 - return; 391 - 392 - /* 393 - * Change 05/01/2003 - Ryan Arnold: If a partition other than 394 - * the current exclusive partition tries to send us data 395 - * events then just drop them on the floor because we don't 396 - * want his stinking data. He isn't authorized to receive 397 - * data because he wasn't the first one to get the console, 398 - * therefore he shouldn't be allowed to send data either. 399 - * This will work without an iSeries fix. 400 - */ 401 - pi = &port_info[port]; 402 - if (pi->lp != event->xSourceLp) 403 - return; 404 - 405 - spin_lock_irqsave(&consolelock, flags); 406 - 407 - n = IN_BUF_SIZE - pi->in_end; 408 - if (n > cevent->len) 409 - n = cevent->len; 410 - if (n > 0) { 411 - memcpy(&pi->in_buf[pi->in_end], cevent->data, n); 412 - pi->in_end += n; 413 - } 414 - spin_unlock_irqrestore(&consolelock, flags); 415 - if (n == 0) 416 - printk(KERN_WARNING "hvc: input buffer overflow\n"); 417 - } 418 - 419 - static void hvc_ack_event(struct HvLpEvent *event) 420 - { 421 - struct viocharlpevent *cevent = (struct viocharlpevent *)event; 422 - unsigned long flags; 423 - u8 port = cevent->virtual_device; 424 - 425 - if (port >= VTTY_PORTS) { 426 - printk(KERN_WARNING "hvc: data on invalid virtual device\n"); 427 - return; 428 - } 429 - 430 - spin_lock_irqsave(&consolelock, flags); 431 - port_info[port].ack = event->xCorrelationToken; 432 - spin_unlock_irqrestore(&consolelock, flags); 433 - } 434 - 435 - static void hvc_config_event(struct HvLpEvent *event) 436 - { 437 - struct viocharlpevent *cevent = (struct viocharlpevent *)event; 438 - 439 - if (cevent->data[0] == 0x01) 440 - printk(KERN_INFO "hvc: window resized to %d: %d: %d: %d\n", 441 - cevent->data[1], cevent->data[2], 442 - cevent->data[3], cevent->data[4]); 443 - else 444 - printk(KERN_WARNING "hvc: unknown config event\n"); 445 - } 446 - 447 - static void hvc_handle_event(struct HvLpEvent *event) 448 - { 449 - int charminor; 450 - 451 - if (event == NULL) 452 - return; 453 - 454 - charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; 455 - switch (charminor) { 456 - case viocharopen: 457 - hvc_open_event(event); 458 - break; 459 - case viocharclose: 460 - hvc_close_event(event); 461 - break; 462 - case viochardata: 463 - hvc_data_event(event); 464 - break; 465 - case viocharack: 466 - hvc_ack_event(event); 467 - break; 468 - case viocharconfig: 469 - hvc_config_event(event); 470 - break; 471 - default: 472 - if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) { 473 - event->xRc = HvLpEvent_Rc_InvalidSubtype; 474 - HvCallEvent_ackLpEvent(event); 475 - } 476 - } 477 - } 478 - 479 - static int __init send_open(HvLpIndex remoteLp, void *sem) 480 - { 481 - return HvCallEvent_signalLpEventFast(remoteLp, 482 - HvLpEvent_Type_VirtualIo, 483 - viomajorsubtype_chario | viocharopen, 484 - HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, 485 - viopath_sourceinst(remoteLp), 486 - viopath_targetinst(remoteLp), 487 - (u64)(unsigned long)sem, VIOVERSION << 16, 488 - 0, 0, 0, 0); 489 - } 490 - 491 - static int __init hvc_vio_init(void) 492 - { 493 - atomic_t wait_flag; 494 - int rc; 495 - 496 - if (!firmware_has_feature(FW_FEATURE_ISERIES)) 497 - return -EIO; 498 - 499 - /* +2 for fudge */ 500 - rc = viopath_open(HvLpConfig_getPrimaryLpIndex(), 501 - viomajorsubtype_chario, VIOCHAR_WINDOW + 2); 502 - if (rc) 503 - printk(KERN_WARNING "hvc: error opening to primary %d\n", rc); 504 - 505 - if (viopath_hostLp == HvLpIndexInvalid) 506 - vio_set_hostlp(); 507 - 508 - /* 509 - * And if the primary is not the same as the hosting LP, open to the 510 - * hosting lp 511 - */ 512 - if ((viopath_hostLp != HvLpIndexInvalid) && 513 - (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) { 514 - printk(KERN_INFO "hvc: open path to hosting (%d)\n", 515 - viopath_hostLp); 516 - rc = viopath_open(viopath_hostLp, viomajorsubtype_chario, 517 - VIOCHAR_WINDOW + 2); /* +2 for fudge */ 518 - if (rc) 519 - printk(KERN_WARNING 520 - "error opening to partition %d: %d\n", 521 - viopath_hostLp, rc); 522 - } 523 - 524 - if (vio_setHandler(viomajorsubtype_chario, hvc_handle_event) < 0) 525 - printk(KERN_WARNING 526 - "hvc: error seting handler for console events!\n"); 527 - 528 - /* 529 - * First, try to open the console to the hosting lp. 530 - * Wait on a semaphore for the response. 531 - */ 532 - atomic_set(&wait_flag, 0); 533 - if ((viopath_isactive(viopath_hostLp)) && 534 - (send_open(viopath_hostLp, &wait_flag) == 0)) { 535 - printk(KERN_INFO "hvc: hosting partition %d\n", viopath_hostLp); 536 - while (atomic_read(&wait_flag) == 0) 537 - mb(); 538 - atomic_set(&wait_flag, 0); 539 - } 540 - 541 - /* 542 - * If we don't have an active console, try the primary 543 - */ 544 - if ((!viopath_isactive(port_info[0].lp)) && 545 - (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) && 546 - (send_open(HvLpConfig_getPrimaryLpIndex(), &wait_flag) == 0)) { 547 - printk(KERN_INFO "hvc: opening console to primary partition\n"); 548 - while (atomic_read(&wait_flag) == 0) 549 - mb(); 550 - } 551 - 552 - /* Register as a vio device to receive callbacks */ 553 - rc = vio_register_driver(&hvc_vio_driver); 554 - 555 - return rc; 556 - } 557 - module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */ 558 - 559 - static void __exit hvc_vio_exit(void) 560 - { 561 - vio_unregister_driver(&hvc_vio_driver); 562 - } 563 - module_exit(hvc_vio_exit); 564 - 565 - /* the device tree order defines our numbering */ 566 - static int __init hvc_find_vtys(void) 567 - { 568 - struct device_node *vty; 569 - int num_found = 0; 570 - 571 - for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL; 572 - vty = of_find_node_by_name(vty, "vty")) { 573 - const uint32_t *vtermno; 574 - 575 - /* We have statically defined space for only a certain number 576 - * of console adapters. 577 - */ 578 - if ((num_found >= MAX_NR_HVC_CONSOLES) || 579 - (num_found >= VTTY_PORTS)) { 580 - of_node_put(vty); 581 - break; 582 - } 583 - 584 - vtermno = of_get_property(vty, "reg", NULL); 585 - if (!vtermno) 586 - continue; 587 - 588 - if (!of_device_is_compatible(vty, "IBM,iSeries-vty")) 589 - continue; 590 - 591 - if (num_found == 0) 592 - add_preferred_console("hvc", 0, NULL); 593 - hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops); 594 - ++num_found; 595 - } 596 - 597 - return num_found; 598 - } 599 - console_initcall(hvc_find_vtys);