void __init hvc_vio_init_early(void) { struct device_node *stdout_node; const u32 *termno; const char *name; const struct hv_ops *ops; if (!of_chosen) return; name = of_get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) return; stdout_node = of_find_node_by_path(name); if (!stdout_node) return; name = of_get_property(stdout_node, "name", NULL); if (!name) { printk(KERN_WARNING "stdout node missing 'name' property!\n"); goto out; } if (strncmp(name, "vty", 3) != 0) goto out; termno = of_get_property(stdout_node, "reg", NULL); if (termno == NULL) goto out; hvterm_priv0.termno = *termno; spin_lock_init(&hvterm_priv0.buf_lock); hvterm_privs[0] = &hvterm_priv0; if (of_device_is_compatible(stdout_node, "hvterm1")) { hvterm_priv0.proto = HV_PROTOCOL_RAW; ops = &hvterm_raw_ops; } else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) { hvterm_priv0.proto = HV_PROTOCOL_HVSI; ops = &hvterm_hvsi_ops; hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars, hvterm_priv0.termno, 1); hvsilib_establish(&hvterm_priv0.hvsi); } else goto out; udbg_putc = udbg_hvc_putc; udbg_getc = udbg_hvc_getc; udbg_getc_poll = udbg_hvc_getc_poll; #ifdef HVC_OLD_HVSI if (hvterm_priv0.proto == HV_PROTOCOL_HVSI) goto out; #endif add_preferred_console("hvc", 0, NULL); hvc_instantiate(0, 0, ops); out: of_node_put(stdout_node); }
void __init hvc_vio_init_early(void) { const __be32 *termno; const char *name; const struct hv_ops *ops; /* find the boot console from /chosen/stdout */ if (!of_stdout) return; name = of_get_property(of_stdout, "name", NULL); if (!name) { printk(KERN_WARNING "stdout node missing 'name' property!\n"); return; } /* Check if it's a virtual terminal */ if (strncmp(name, "vty", 3) != 0) return; termno = of_get_property(of_stdout, "reg", NULL); if (termno == NULL) return; hvterm_priv0.termno = of_read_number(termno, 1); spin_lock_init(&hvterm_priv0.buf_lock); hvterm_privs[0] = &hvterm_priv0; /* Check the protocol */ if (of_device_is_compatible(of_stdout, "hvterm1")) { hvterm_priv0.proto = HV_PROTOCOL_RAW; ops = &hvterm_raw_ops; } else if (of_device_is_compatible(of_stdout, "hvterm-protocol")) { hvterm_priv0.proto = HV_PROTOCOL_HVSI; ops = &hvterm_hvsi_ops; hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars, hvterm_priv0.termno, 1); /* HVSI, perform the handshake now */ hvsilib_establish(&hvterm_priv0.hvsi); } else return; udbg_putc = udbg_hvc_putc; udbg_getc = udbg_hvc_getc; udbg_getc_poll = udbg_hvc_getc_poll; #ifdef HVC_OLD_HVSI /* When using the old HVSI driver don't register the HVC * backend for HVSI, only do udbg */ if (hvterm_priv0.proto == HV_PROTOCOL_HVSI) return; #endif /* Check whether the user has requested a different console. */ if (!strstr(boot_command_line, "console=")) add_preferred_console("hvc", 0, NULL); hvc_instantiate(0, 0, ops); }
void __init udbg_init_debug_lpar_hvsi(void) { hvterm_privs[0] = &hvterm_priv0; hvterm_priv0.termno = CONFIG_PPC_EARLY_DEBUG_HVSI_VTERMNO; hvterm_priv0.proto = HV_PROTOCOL_HVSI; spin_lock_init(&hvterm_priv0.buf_lock); udbg_putc = udbg_hvc_putc; udbg_getc = udbg_hvc_getc; udbg_getc_poll = udbg_hvc_getc_poll; hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars, hvterm_priv0.termno, 1); hvsilib_establish(&hvterm_priv0.hvsi); }
static int __devinit hvc_vio_probe(struct vio_dev *vdev, const struct vio_device_id *id) { const struct hv_ops *ops; struct hvc_struct *hp; struct hvterm_priv *pv; hv_protocol_t proto; int i, termno = -1; /* */ if (!vdev || !id) return -EPERM; if (of_device_is_compatible(vdev->dev.of_node, "hvterm1")) { proto = HV_PROTOCOL_RAW; ops = &hvterm_raw_ops; } else if (of_device_is_compatible(vdev->dev.of_node, "hvterm-protocol")) { proto = HV_PROTOCOL_HVSI; ops = &hvterm_hvsi_ops; } else { pr_err("hvc_vio: Unkown protocol for %s\n", vdev->dev.of_node->full_name); return -ENXIO; } pr_devel("hvc_vio_probe() device %s, using %s protocol\n", vdev->dev.of_node->full_name, proto == HV_PROTOCOL_RAW ? "raw" : "hvsi"); /* */ if (hvterm_privs[0] == &hvterm_priv0 && vdev->unit_address == hvterm_priv0.termno) { pv = hvterm_privs[0]; termno = 0; pr_devel("->boot console, using termno 0\n"); } /* */ else { for (i = 0; i < MAX_NR_HVC_CONSOLES && termno < 0; i++) if (!hvterm_privs[i]) termno = i; pr_devel("->non-boot console, using termno %d\n", termno); if (termno < 0) return -ENODEV; pv = kzalloc(sizeof(struct hvterm_priv), GFP_KERNEL); if (!pv) return -ENOMEM; pv->termno = vdev->unit_address; pv->proto = proto; spin_lock_init(&pv->buf_lock); hvterm_privs[termno] = pv; hvsilib_init(&pv->hvsi, hvc_get_chars, hvc_put_chars, pv->termno, 0); } hp = hvc_alloc(termno, vdev->irq, ops, MAX_VIO_PUT_CHARS); if (IS_ERR(hp)) return PTR_ERR(hp); dev_set_drvdata(&vdev->dev, hp); return 0; }
void __init hvc_vio_init_early(void) { struct device_node *stdout_node; const u32 *termno; const char *name; const struct hv_ops *ops; /* find the boot console from /chosen/stdout */ if (!of_chosen) return; name = of_get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) return; stdout_node = of_find_node_by_path(name); if (!stdout_node) return; name = of_get_property(stdout_node, "name", NULL); if (!name) { printk(KERN_WARNING "stdout node missing 'name' property!\n"); goto out; } /* Check if it's a virtual terminal */ if (strncmp(name, "vty", 3) != 0) goto out; termno = of_get_property(stdout_node, "reg", NULL); if (termno == NULL) goto out; hvterm_priv0.termno = *termno; spin_lock_init(&hvterm_priv0.buf_lock); hvterm_privs[0] = &hvterm_priv0; /* Check the protocol */ if (of_device_is_compatible(stdout_node, "hvterm1")) { hvterm_priv0.proto = HV_PROTOCOL_RAW; ops = &hvterm_raw_ops; } else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) { hvterm_priv0.proto = HV_PROTOCOL_HVSI; ops = &hvterm_hvsi_ops; hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars, hvterm_priv0.termno, 1); /* HVSI, perform the handshake now */ hvsilib_establish(&hvterm_priv0.hvsi); } else goto out; udbg_putc = udbg_hvc_putc; udbg_getc = udbg_hvc_getc; udbg_getc_poll = udbg_hvc_getc_poll; #ifdef HVC_OLD_HVSI /* When using the old HVSI driver don't register the HVC * backend for HVSI, only do udbg */ if (hvterm_priv0.proto == HV_PROTOCOL_HVSI) goto out; #endif add_preferred_console("hvc", 0, NULL); hvc_instantiate(0, 0, ops); out: of_node_put(stdout_node); }
static int hvc_vio_probe(struct vio_dev *vdev, const struct vio_device_id *id) { const struct hv_ops *ops; struct hvc_struct *hp; struct hvterm_priv *pv; hv_protocol_t proto; int i, termno = -1; /* probed with invalid parameters. */ if (!vdev || !id) return -EPERM; if (of_device_is_compatible(vdev->dev.of_node, "hvterm1")) { proto = HV_PROTOCOL_RAW; ops = &hvterm_raw_ops; } else if (of_device_is_compatible(vdev->dev.of_node, "hvterm-protocol")) { proto = HV_PROTOCOL_HVSI; ops = &hvterm_hvsi_ops; } else { pr_err("hvc_vio: Unknown protocol for %pOF\n", vdev->dev.of_node); return -ENXIO; } pr_devel("hvc_vio_probe() device %pOF, using %s protocol\n", vdev->dev.of_node, proto == HV_PROTOCOL_RAW ? "raw" : "hvsi"); /* Is it our boot one ? */ if (hvterm_privs[0] == &hvterm_priv0 && vdev->unit_address == hvterm_priv0.termno) { pv = hvterm_privs[0]; termno = 0; pr_devel("->boot console, using termno 0\n"); } /* nope, allocate a new one */ else { for (i = 0; i < MAX_NR_HVC_CONSOLES && termno < 0; i++) if (!hvterm_privs[i]) termno = i; pr_devel("->non-boot console, using termno %d\n", termno); if (termno < 0) return -ENODEV; pv = kzalloc(sizeof(struct hvterm_priv), GFP_KERNEL); if (!pv) return -ENOMEM; pv->termno = vdev->unit_address; pv->proto = proto; spin_lock_init(&pv->buf_lock); hvterm_privs[termno] = pv; hvsilib_init(&pv->hvsi, hvc_get_chars, hvc_put_chars, pv->termno, 0); } hp = hvc_alloc(termno, vdev->irq, ops, MAX_VIO_PUT_CHARS); if (IS_ERR(hp)) return PTR_ERR(hp); dev_set_drvdata(&vdev->dev, hp); /* register udbg if it's not there already for console 0 */ if (hp->index == 0 && !udbg_putc) { udbg_putc = udbg_hvc_putc; udbg_getc = udbg_hvc_getc; udbg_getc_poll = udbg_hvc_getc_poll; } return 0; }