struct hvc_opal_priv {
hv_protocol_t proto; /* Raw data or HVSI packets */ struct hvsi_priv hvsi; /* HVSI specific data */
}; staticstruct hvc_opal_priv *hvc_opal_privs[MAX_NR_HVC_CONSOLES];
/* For early boot console */ staticstruct hvc_opal_priv hvc_opal_boot_priv; static u32 hvc_opal_boot_termno;
staticint __init hvc_opal_init(void)
{ if (!firmware_has_feature(FW_FEATURE_OPAL)) return -ENODEV;
/* Register as a vio device to receive callbacks */ return platform_driver_register(&hvc_opal_driver);
}
device_initcall(hvc_opal_init);
staticvoid udbg_opal_putc(char c)
{ unsignedint termno = hvc_opal_boot_termno; int count = -1;
if (c == '\n')
udbg_opal_putc('\r');
do { switch(hvc_opal_boot_priv.proto) { case HV_PROTOCOL_RAW:
count = opal_put_chars(termno, &c, 1); break; case HV_PROTOCOL_HVSI:
count = hvc_opal_hvsi_put_chars(termno, &c, 1); break;
}
/* This is needed for the cosole to flush * when there aren't any interrupts.
*/
opal_flush_console(termno);
} while(count == 0 || count == -EAGAIN);
}
/* If the console wasn't in /chosen, try /ibm,opal */ if (!stdout_node) { struct device_node *opal, *np;
/* Current OPAL takeover doesn't provide the stdout * path, so we hard wire it
*/
opal = of_find_node_by_path("/ibm,opal/consoles"); if (opal) {
pr_devel("hvc_opal: Found consoles in new location\n");
} else {
opal = of_find_node_by_path("/ibm,opal"); if (opal)
pr_devel("hvc_opal: " "Found consoles in old location\n");
} if (!opal) return;
for_each_child_of_node(opal, np) { if (of_node_name_eq(np, "serial")) {
stdout_node = np; break;
}
}
of_node_put(opal);
} if (!stdout_node) return;
termno = of_get_property(stdout_node, "reg", NULL);
index = termno ? be32_to_cpup(termno) : 0; if (index >= MAX_NR_HVC_CONSOLES) return;
hvc_opal_privs[index] = &hvc_opal_boot_priv;
/* Check the protocol */ if (of_device_is_compatible(stdout_node, "ibm,opal-console-raw")) {
hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW;
ops = &hvc_opal_raw_ops;
pr_devel("hvc_opal: Found RAW console\n");
} elseif (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) {
hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI;
ops = &hvc_opal_hvsi_ops;
hvsilib_init(&hvc_opal_boot_priv.hvsi,
opal_get_chars, opal_put_chars_atomic,
index, 1); /* HVSI, perform the handshake now */
hvsilib_establish(&hvc_opal_boot_priv.hvsi);
pr_devel("hvc_opal: Found HVSI console\n");
} else goto out;
hvc_opal_boot_termno = index;
udbg_init_opal_common();
add_preferred_console("hvc", index, NULL);
hvc_instantiate(index, index, ops);
out:
of_node_put(stdout_node);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.