1daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt/* 2daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * opal driver interface to hvc_console.c 3daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * 4daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * Copyright 2011 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. 5daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * 6daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * This program is free software; you can redistribute it and/or modify 7daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * it under the terms of the GNU General Public License as published by 8daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * the Free Software Foundation; either version 2 of the License, or 9daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * (at your option) any later version. 10daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * 11daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * This program is distributed in the hope that it will be useful, 12daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * but WITHOUT ANY WARRANTY; without even the implied warranty of 13daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * GNU General Public License for more details. 15daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * 16daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * You should have received a copy of the GNU General Public License 17daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * along with this program; if not, write to the Free Software 18daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * 20daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt */ 21daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 22daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#undef DEBUG 23daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 24daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <linux/types.h> 25daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <linux/init.h> 26daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <linux/delay.h> 27daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <linux/slab.h> 28daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <linux/console.h> 29daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <linux/of.h> 30daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <linux/of_platform.h> 310084e4751e63a71b30f315710f976f8bb0c2cc07Michael Neuling#include <linux/export.h> 32daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 33daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <asm/hvconsole.h> 34daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <asm/prom.h> 35daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <asm/firmware.h> 36daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <asm/hvsi.h> 37daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <asm/udbg.h> 38daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include <asm/opal.h> 39daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 40daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#include "hvc_console.h" 41daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 42daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic const char hvc_opal_name[] = "hvc_opal"; 43daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 44daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic struct of_device_id hvc_opal_match[] __devinitdata = { 45daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt { .name = "serial", .compatible = "ibm,opal-console-raw" }, 46daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt { .name = "serial", .compatible = "ibm,opal-console-hvsi" }, 47daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt { }, 48daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt}; 49daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 50daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidttypedef enum hv_protocol { 51daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt HV_PROTOCOL_RAW, 52daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt HV_PROTOCOL_HVSI 53daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} hv_protocol_t; 54daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 55daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstruct hvc_opal_priv { 56daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hv_protocol_t proto; /* Raw data or HVSI packets */ 57daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvsi_priv hvsi; /* HVSI specific data */ 58daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt}; 59daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic struct hvc_opal_priv *hvc_opal_privs[MAX_NR_HVC_CONSOLES]; 60daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 61daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt/* For early boot console */ 62daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic struct hvc_opal_priv hvc_opal_boot_priv; 63daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic u32 hvc_opal_boot_termno; 64daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 65daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic const struct hv_ops hvc_opal_raw_ops = { 66daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .get_chars = opal_get_chars, 67daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .put_chars = opal_put_chars, 68daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .notifier_add = notifier_add_irq, 69daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .notifier_del = notifier_del_irq, 70daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .notifier_hangup = notifier_hangup_irq, 71daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt}; 72daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 73daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int hvc_opal_hvsi_get_chars(uint32_t vtermno, char *buf, int count) 74daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 75daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv = hvc_opal_privs[vtermno]; 76daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 77daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (WARN_ON(!pv)) 78daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -ENODEV; 79daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 80daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return hvsilib_get_chars(&pv->hvsi, buf, count); 81daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 82daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 83daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int hvc_opal_hvsi_put_chars(uint32_t vtermno, const char *buf, int count) 84daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 85daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv = hvc_opal_privs[vtermno]; 86daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 87daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (WARN_ON(!pv)) 88daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -ENODEV; 89daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 90daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return hvsilib_put_chars(&pv->hvsi, buf, count); 91daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 92daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 93daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int hvc_opal_hvsi_open(struct hvc_struct *hp, int data) 94daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 95daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; 96daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt int rc; 97daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 98daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("HVSI@%x: do open !\n", hp->vtermno); 99daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 100daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt rc = notifier_add_irq(hp, data); 101daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (rc) 102daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return rc; 103daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 104daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return hvsilib_open(&pv->hvsi, hp); 105daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 106daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 107daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic void hvc_opal_hvsi_close(struct hvc_struct *hp, int data) 108daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 109daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; 110daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 111daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("HVSI@%x: do close !\n", hp->vtermno); 112daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 113daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_close(&pv->hvsi, hp); 114daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 115daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt notifier_del_irq(hp, data); 116daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 117daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 118daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtvoid hvc_opal_hvsi_hangup(struct hvc_struct *hp, int data) 119daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 120daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; 121daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 122daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("HVSI@%x: do hangup !\n", hp->vtermno); 123daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 124daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_close(&pv->hvsi, hp); 125daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 126daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt notifier_hangup_irq(hp, data); 127daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 128daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 129daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int hvc_opal_hvsi_tiocmget(struct hvc_struct *hp) 130daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 131daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; 132daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 133daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!pv) 134daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -EINVAL; 135daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return pv->hvsi.mctrl; 136daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 137daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 138daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set, 139daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt unsigned int clear) 140daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 141daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno]; 142daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 143daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("HVSI@%x: Set modem control, set=%x,clr=%x\n", 144daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hp->vtermno, set, clear); 145daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 146daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (set & TIOCM_DTR) 147daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_write_mctrl(&pv->hvsi, 1); 148daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt else if (clear & TIOCM_DTR) 149daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_write_mctrl(&pv->hvsi, 0); 150daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 151daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return 0; 152daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 153daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 154daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic const struct hv_ops hvc_opal_hvsi_ops = { 155daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .get_chars = hvc_opal_hvsi_get_chars, 156daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .put_chars = hvc_opal_hvsi_put_chars, 157daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .notifier_add = hvc_opal_hvsi_open, 158daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .notifier_del = hvc_opal_hvsi_close, 159daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .notifier_hangup = hvc_opal_hvsi_hangup, 160daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .tiocmget = hvc_opal_hvsi_tiocmget, 161daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .tiocmset = hvc_opal_hvsi_tiocmset, 162daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt}; 163daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 164daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int __devinit hvc_opal_probe(struct platform_device *dev) 165daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 166daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt const struct hv_ops *ops; 167daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_struct *hp; 168daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_opal_priv *pv; 169daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hv_protocol_t proto; 170daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt unsigned int termno, boot = 0; 171daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt const __be32 *reg; 172daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 173daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) { 174daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt proto = HV_PROTOCOL_RAW; 175daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt ops = &hvc_opal_raw_ops; 176daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } else if (of_device_is_compatible(dev->dev.of_node, 177daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt "ibm,opal-console-hvsi")) { 178daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt proto = HV_PROTOCOL_HVSI; 179daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt ops = &hvc_opal_hvsi_ops; 180daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } else { 181daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_err("hvc_opal: Unkown protocol for %s\n", 182daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt dev->dev.of_node->full_name); 183daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -ENXIO; 184daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 185daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 186daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt reg = of_get_property(dev->dev.of_node, "reg", NULL); 187daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt termno = reg ? be32_to_cpup(reg) : 0; 188daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 189daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* Is it our boot one ? */ 190daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (hvc_opal_privs[termno] == &hvc_opal_boot_priv) { 191daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pv = hvc_opal_privs[termno]; 192daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt boot = 1; 193daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } else if (hvc_opal_privs[termno] == NULL) { 194daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pv = kzalloc(sizeof(struct hvc_opal_priv), GFP_KERNEL); 195daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!pv) 196daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -ENOMEM; 197daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pv->proto = proto; 198daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_privs[termno] = pv; 199daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (proto == HV_PROTOCOL_HVSI) 200daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_init(&pv->hvsi, opal_get_chars, opal_put_chars, 201daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt termno, 0); 202daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 203daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* Instanciate now to establish a mapping index==vtermno */ 204daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_instantiate(termno, termno, ops); 205daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } else { 206daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n", 207daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt dev->dev.of_node->full_name, termno); 208daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -ENXIO; 209daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 210daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 211daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_info("hvc%d: %s protocol on %s%s\n", termno, 212daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt proto == HV_PROTOCOL_RAW ? "raw" : "hvsi", 213daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt dev->dev.of_node->full_name, 214daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt boot ? " (boot console)" : ""); 215daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 216daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* We don't do IRQ yet */ 217daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hp = hvc_alloc(termno, 0, ops, MAX_VIO_PUT_CHARS); 218daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (IS_ERR(hp)) 219daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return PTR_ERR(hp); 220daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt dev_set_drvdata(&dev->dev, hp); 221daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 222daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return 0; 223daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 224daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 225daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int __devexit hvc_opal_remove(struct platform_device *dev) 226daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 227daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct hvc_struct *hp = dev_get_drvdata(&dev->dev); 228daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt int rc, termno; 229daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 230daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt termno = hp->vtermno; 231daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt rc = hvc_remove(hp); 232daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (rc == 0) { 233daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (hvc_opal_privs[termno] != &hvc_opal_boot_priv) 234daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt kfree(hvc_opal_privs[termno]); 235daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_privs[termno] = NULL; 236daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 237daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return rc; 238daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 239daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 240daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic struct platform_driver hvc_opal_driver = { 241daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .probe = hvc_opal_probe, 242daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .remove = __devexit_p(hvc_opal_remove), 243daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .driver = { 244daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .name = hvc_opal_name, 245daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .owner = THIS_MODULE, 246daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt .of_match_table = hvc_opal_match, 247daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 248daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt}; 249daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 250daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int __init hvc_opal_init(void) 251daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 252daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!firmware_has_feature(FW_FEATURE_OPAL)) 253daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -ENODEV; 254daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 255daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* Register as a vio device to receive callbacks */ 256daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return platform_driver_register(&hvc_opal_driver); 257daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 258daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtmodule_init(hvc_opal_init); 259daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 260daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic void __exit hvc_opal_exit(void) 261daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 262daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt platform_driver_unregister(&hvc_opal_driver); 263daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 264daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtmodule_exit(hvc_opal_exit); 265daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 266daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic void udbg_opal_putc(char c) 267daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 268daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt unsigned int termno = hvc_opal_boot_termno; 269daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt int count = -1; 270daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 271daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (c == '\n') 272daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt udbg_opal_putc('\r'); 273daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 274daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt do { 275daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt switch(hvc_opal_boot_priv.proto) { 276daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt case HV_PROTOCOL_RAW: 277daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt count = opal_put_chars(termno, &c, 1); 278daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt break; 279daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt case HV_PROTOCOL_HVSI: 280daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt count = hvc_opal_hvsi_put_chars(termno, &c, 1); 281daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt break; 282daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 283daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } while(count == 0 || count == -EAGAIN); 284daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 285daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 286daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int udbg_opal_getc_poll(void) 287daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 288daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt unsigned int termno = hvc_opal_boot_termno; 289daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt int rc = 0; 290daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt char c; 291daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 292daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt switch(hvc_opal_boot_priv.proto) { 293daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt case HV_PROTOCOL_RAW: 294daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt rc = opal_get_chars(termno, &c, 1); 295daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt break; 296daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt case HV_PROTOCOL_HVSI: 297daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt rc = hvc_opal_hvsi_get_chars(termno, &c, 1); 298daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt break; 299daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 300daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!rc) 301daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return -1; 302daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return c; 303daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 304daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 305daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic int udbg_opal_getc(void) 306daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 307daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt int ch; 308daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt for (;;) { 309daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt ch = udbg_opal_getc_poll(); 310daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (ch == -1) { 311daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* This shouldn't be needed...but... */ 312daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt volatile unsigned long delay; 313daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt for (delay=0; delay < 2000000; delay++) 314daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt ; 315daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } else { 316daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return ch; 317daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 318daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 319daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 320daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 321daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtstatic void udbg_init_opal_common(void) 322daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 323daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt udbg_putc = udbg_opal_putc; 324daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt udbg_getc = udbg_opal_getc; 325daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt udbg_getc_poll = udbg_opal_getc_poll; 326daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt tb_ticks_per_usec = 0x200; /* Make udelay not suck */ 327daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 328daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 329daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtvoid __init hvc_opal_init_early(void) 330daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 331daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct device_node *stdout_node = NULL; 332daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt const u32 *termno; 333daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt const char *name = NULL; 334daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt const struct hv_ops *ops; 335daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt u32 index; 336daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 337daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* find the boot console from /chosen/stdout */ 338daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (of_chosen) 339daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt name = of_get_property(of_chosen, "linux,stdout-path", NULL); 340daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (name) { 341daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt stdout_node = of_find_node_by_path(name); 342daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!stdout_node) { 343daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_err("hvc_opal: Failed to locate default console!\n"); 344daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return; 345daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 346daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } else { 347daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt struct device_node *opal, *np; 348daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 349daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* Current OPAL takeover doesn't provide the stdout 350daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt * path, so we hard wire it 351daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt */ 352daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt opal = of_find_node_by_path("/ibm,opal/consoles"); 353daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (opal) 354daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("hvc_opal: Found consoles in new location\n"); 355daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!opal) { 356daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt opal = of_find_node_by_path("/ibm,opal"); 357daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (opal) 358daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("hvc_opal: " 359daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt "Found consoles in old location\n"); 360daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 361daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!opal) 362daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return; 363daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt for_each_child_of_node(opal, np) { 364daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!strcmp(np->name, "serial")) { 365daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt stdout_node = np; 366daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt break; 367daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 368daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 369daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt of_node_put(opal); 370daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 371daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (!stdout_node) 372daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return; 373daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt termno = of_get_property(stdout_node, "reg", NULL); 374daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt index = termno ? *termno : 0; 375daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (index >= MAX_NR_HVC_CONSOLES) 376daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt return; 377daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_privs[index] = &hvc_opal_boot_priv; 378daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 379daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* Check the protocol */ 380daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt if (of_device_is_compatible(stdout_node, "ibm,opal-console-raw")) { 381daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW; 382daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt ops = &hvc_opal_raw_ops; 383daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("hvc_opal: Found RAW console\n"); 384daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } 385daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt else if (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) { 386daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI; 387daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt ops = &hvc_opal_hvsi_ops; 388daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, 389daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt opal_put_chars, index, 1); 390daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt /* HVSI, perform the handshake now */ 391daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_establish(&hvc_opal_boot_priv.hvsi); 392daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt pr_devel("hvc_opal: Found HVSI console\n"); 393daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt } else 394daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt goto out; 395daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_boot_termno = index; 396daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt udbg_init_opal_common(); 397daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt add_preferred_console("hvc", index, NULL); 398daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_instantiate(index, index, ops); 399daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtout: 400daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt of_node_put(stdout_node); 401daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 402daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 403daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_RAW 404daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtvoid __init udbg_init_debug_opal(void) 405daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 406daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO; 407daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_privs[index] = &hvc_opal_boot_priv; 408daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW; 409daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_boot_termno = index; 410daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt udbg_init_opal_common(); 411daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 412daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_RAW */ 413daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt 414daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI 415daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidtvoid __init udbg_init_debug_opal_hvsi(void) 416daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt{ 417daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO; 418daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_privs[index] = &hvc_opal_boot_priv; 419daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvc_opal_boot_termno = index; 420daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt udbg_init_opal_common(); 421daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, opal_put_chars, 422daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt index, 1); 423daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt hvsilib_establish(&hvc_opal_boot_priv.hvsi); 424daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt} 425daea1175a9f0f70eab5b33e2827d57ba8c686816Benjamin Herrenschmidt#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI */ 426