0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #undef DEBUG
0025
0026 #include <linux/types.h>
0027 #include <linux/init.h>
0028 #include <linux/delay.h>
0029 #include <linux/slab.h>
0030 #include <linux/console.h>
0031 #include <linux/of.h>
0032
0033 #include <asm/hvconsole.h>
0034 #include <asm/vio.h>
0035 #include <asm/hvsi.h>
0036 #include <asm/udbg.h>
0037 #include <asm/machdep.h>
0038
0039 #include "hvc_console.h"
0040
0041 static const char hvc_driver_name[] = "hvc_console";
0042
0043 static const struct vio_device_id hvc_driver_table[] = {
0044 {"serial", "hvterm1"},
0045 #ifndef HVC_OLD_HVSI
0046 {"serial", "hvterm-protocol"},
0047 #endif
0048 { "", "" }
0049 };
0050
0051 typedef enum hv_protocol {
0052 HV_PROTOCOL_RAW,
0053 HV_PROTOCOL_HVSI
0054 } hv_protocol_t;
0055
0056 struct hvterm_priv {
0057 u32 termno;
0058 hv_protocol_t proto;
0059 struct hvsi_priv hvsi;
0060 spinlock_t buf_lock;
0061 char buf[SIZE_VIO_GET_CHARS];
0062 int left;
0063 int offset;
0064 };
0065 static struct hvterm_priv *hvterm_privs[MAX_NR_HVC_CONSOLES];
0066
0067 static struct hvterm_priv hvterm_priv0;
0068
0069 static int hvterm_raw_get_chars(uint32_t vtermno, char *buf, int count)
0070 {
0071 struct hvterm_priv *pv = hvterm_privs[vtermno];
0072 unsigned long i;
0073 unsigned long flags;
0074 int got;
0075
0076 if (WARN_ON(!pv))
0077 return 0;
0078
0079 spin_lock_irqsave(&pv->buf_lock, flags);
0080
0081 if (pv->left == 0) {
0082 pv->offset = 0;
0083 pv->left = hvc_get_chars(pv->termno, pv->buf, count);
0084
0085
0086
0087
0088
0089 for (i = 1; i < pv->left; ++i) {
0090 if (pv->buf[i] == 0 && pv->buf[i-1] == '\r') {
0091 --pv->left;
0092 if (i < pv->left) {
0093 memmove(&pv->buf[i], &pv->buf[i+1],
0094 pv->left - i);
0095 }
0096 }
0097 }
0098 }
0099
0100 got = min(count, pv->left);
0101 memcpy(buf, &pv->buf[pv->offset], got);
0102 pv->offset += got;
0103 pv->left -= got;
0104
0105 spin_unlock_irqrestore(&pv->buf_lock, flags);
0106
0107 return got;
0108 }
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 static int hvterm_raw_put_chars(uint32_t vtermno, const char *buf, int count)
0119 {
0120 struct hvterm_priv *pv = hvterm_privs[vtermno];
0121
0122 if (WARN_ON(!pv))
0123 return 0;
0124
0125 return hvc_put_chars(pv->termno, buf, count);
0126 }
0127
0128 static const struct hv_ops hvterm_raw_ops = {
0129 .get_chars = hvterm_raw_get_chars,
0130 .put_chars = hvterm_raw_put_chars,
0131 .notifier_add = notifier_add_irq,
0132 .notifier_del = notifier_del_irq,
0133 .notifier_hangup = notifier_hangup_irq,
0134 };
0135
0136 static int hvterm_hvsi_get_chars(uint32_t vtermno, char *buf, int count)
0137 {
0138 struct hvterm_priv *pv = hvterm_privs[vtermno];
0139
0140 if (WARN_ON(!pv))
0141 return 0;
0142
0143 return hvsilib_get_chars(&pv->hvsi, buf, count);
0144 }
0145
0146 static int hvterm_hvsi_put_chars(uint32_t vtermno, const char *buf, int count)
0147 {
0148 struct hvterm_priv *pv = hvterm_privs[vtermno];
0149
0150 if (WARN_ON(!pv))
0151 return 0;
0152
0153 return hvsilib_put_chars(&pv->hvsi, buf, count);
0154 }
0155
0156 static int hvterm_hvsi_open(struct hvc_struct *hp, int data)
0157 {
0158 struct hvterm_priv *pv = hvterm_privs[hp->vtermno];
0159 int rc;
0160
0161 pr_devel("HVSI@%x: open !\n", pv->termno);
0162
0163 rc = notifier_add_irq(hp, data);
0164 if (rc)
0165 return rc;
0166
0167 return hvsilib_open(&pv->hvsi, hp);
0168 }
0169
0170 static void hvterm_hvsi_close(struct hvc_struct *hp, int data)
0171 {
0172 struct hvterm_priv *pv = hvterm_privs[hp->vtermno];
0173
0174 pr_devel("HVSI@%x: do close !\n", pv->termno);
0175
0176 hvsilib_close(&pv->hvsi, hp);
0177
0178 notifier_del_irq(hp, data);
0179 }
0180
0181 static void hvterm_hvsi_hangup(struct hvc_struct *hp, int data)
0182 {
0183 struct hvterm_priv *pv = hvterm_privs[hp->vtermno];
0184
0185 pr_devel("HVSI@%x: do hangup !\n", pv->termno);
0186
0187 hvsilib_close(&pv->hvsi, hp);
0188
0189 notifier_hangup_irq(hp, data);
0190 }
0191
0192 static int hvterm_hvsi_tiocmget(struct hvc_struct *hp)
0193 {
0194 struct hvterm_priv *pv = hvterm_privs[hp->vtermno];
0195
0196 if (!pv)
0197 return -EINVAL;
0198 return pv->hvsi.mctrl;
0199 }
0200
0201 static int hvterm_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set,
0202 unsigned int clear)
0203 {
0204 struct hvterm_priv *pv = hvterm_privs[hp->vtermno];
0205
0206 pr_devel("HVSI@%x: Set modem control, set=%x,clr=%x\n",
0207 pv->termno, set, clear);
0208
0209 if (set & TIOCM_DTR)
0210 hvsilib_write_mctrl(&pv->hvsi, 1);
0211 else if (clear & TIOCM_DTR)
0212 hvsilib_write_mctrl(&pv->hvsi, 0);
0213
0214 return 0;
0215 }
0216
0217 static const struct hv_ops hvterm_hvsi_ops = {
0218 .get_chars = hvterm_hvsi_get_chars,
0219 .put_chars = hvterm_hvsi_put_chars,
0220 .notifier_add = hvterm_hvsi_open,
0221 .notifier_del = hvterm_hvsi_close,
0222 .notifier_hangup = hvterm_hvsi_hangup,
0223 .tiocmget = hvterm_hvsi_tiocmget,
0224 .tiocmset = hvterm_hvsi_tiocmset,
0225 };
0226
0227 static void udbg_hvc_putc(char c)
0228 {
0229 int count = -1;
0230 unsigned char bounce_buffer[16];
0231
0232 if (!hvterm_privs[0])
0233 return;
0234
0235 if (c == '\n')
0236 udbg_hvc_putc('\r');
0237
0238 do {
0239 switch(hvterm_privs[0]->proto) {
0240 case HV_PROTOCOL_RAW:
0241
0242
0243
0244
0245 bounce_buffer[0] = c;
0246 count = hvterm_raw_put_chars(0, bounce_buffer, 1);
0247 break;
0248 case HV_PROTOCOL_HVSI:
0249 count = hvterm_hvsi_put_chars(0, &c, 1);
0250 break;
0251 }
0252 } while (count == 0 || count == -EAGAIN);
0253 }
0254
0255 static int udbg_hvc_getc_poll(void)
0256 {
0257 int rc = 0;
0258 char c;
0259
0260 if (!hvterm_privs[0])
0261 return -1;
0262
0263 switch(hvterm_privs[0]->proto) {
0264 case HV_PROTOCOL_RAW:
0265 rc = hvterm_raw_get_chars(0, &c, 1);
0266 break;
0267 case HV_PROTOCOL_HVSI:
0268 rc = hvterm_hvsi_get_chars(0, &c, 1);
0269 break;
0270 }
0271 if (!rc)
0272 return -1;
0273 return c;
0274 }
0275
0276 static int udbg_hvc_getc(void)
0277 {
0278 int ch;
0279
0280 if (!hvterm_privs[0])
0281 return -1;
0282
0283 for (;;) {
0284 ch = udbg_hvc_getc_poll();
0285 if (ch == -1) {
0286
0287 volatile unsigned long delay;
0288 for (delay=0; delay < 2000000; delay++)
0289 ;
0290 } else {
0291 return ch;
0292 }
0293 }
0294 }
0295
0296 static int hvc_vio_probe(struct vio_dev *vdev,
0297 const struct vio_device_id *id)
0298 {
0299 const struct hv_ops *ops;
0300 struct hvc_struct *hp;
0301 struct hvterm_priv *pv;
0302 hv_protocol_t proto;
0303 int i, termno = -1;
0304
0305
0306 if (!vdev || !id)
0307 return -EPERM;
0308
0309 if (of_device_is_compatible(vdev->dev.of_node, "hvterm1")) {
0310 proto = HV_PROTOCOL_RAW;
0311 ops = &hvterm_raw_ops;
0312 } else if (of_device_is_compatible(vdev->dev.of_node, "hvterm-protocol")) {
0313 proto = HV_PROTOCOL_HVSI;
0314 ops = &hvterm_hvsi_ops;
0315 } else {
0316 pr_err("hvc_vio: Unknown protocol for %pOF\n", vdev->dev.of_node);
0317 return -ENXIO;
0318 }
0319
0320 pr_devel("hvc_vio_probe() device %pOF, using %s protocol\n",
0321 vdev->dev.of_node,
0322 proto == HV_PROTOCOL_RAW ? "raw" : "hvsi");
0323
0324
0325 if (hvterm_privs[0] == &hvterm_priv0 &&
0326 vdev->unit_address == hvterm_priv0.termno) {
0327 pv = hvterm_privs[0];
0328 termno = 0;
0329 pr_devel("->boot console, using termno 0\n");
0330 }
0331
0332 else {
0333 for (i = 0; i < MAX_NR_HVC_CONSOLES && termno < 0; i++)
0334 if (!hvterm_privs[i])
0335 termno = i;
0336 pr_devel("->non-boot console, using termno %d\n", termno);
0337 if (termno < 0)
0338 return -ENODEV;
0339 pv = kzalloc(sizeof(struct hvterm_priv), GFP_KERNEL);
0340 if (!pv)
0341 return -ENOMEM;
0342 pv->termno = vdev->unit_address;
0343 pv->proto = proto;
0344 spin_lock_init(&pv->buf_lock);
0345 hvterm_privs[termno] = pv;
0346 hvsilib_init(&pv->hvsi, hvc_get_chars, hvc_put_chars,
0347 pv->termno, 0);
0348 }
0349
0350 hp = hvc_alloc(termno, vdev->irq, ops, MAX_VIO_PUT_CHARS);
0351 if (IS_ERR(hp))
0352 return PTR_ERR(hp);
0353 dev_set_drvdata(&vdev->dev, hp);
0354
0355
0356 if (hp->index == 0 && !udbg_putc) {
0357 udbg_putc = udbg_hvc_putc;
0358 udbg_getc = udbg_hvc_getc;
0359 udbg_getc_poll = udbg_hvc_getc_poll;
0360 }
0361
0362 return 0;
0363 }
0364
0365 static struct vio_driver hvc_vio_driver = {
0366 .id_table = hvc_driver_table,
0367 .probe = hvc_vio_probe,
0368 .name = hvc_driver_name,
0369 .driver = {
0370 .suppress_bind_attrs = true,
0371 },
0372 };
0373
0374 static int __init hvc_vio_init(void)
0375 {
0376 int rc;
0377
0378
0379 rc = vio_register_driver(&hvc_vio_driver);
0380
0381 return rc;
0382 }
0383 device_initcall(hvc_vio_init);
0384
0385 void __init hvc_vio_init_early(void)
0386 {
0387 const __be32 *termno;
0388 const struct hv_ops *ops;
0389
0390
0391
0392 if (!of_node_name_prefix(of_stdout, "vty"))
0393 return;
0394 termno = of_get_property(of_stdout, "reg", NULL);
0395 if (termno == NULL)
0396 return;
0397 hvterm_priv0.termno = of_read_number(termno, 1);
0398 spin_lock_init(&hvterm_priv0.buf_lock);
0399 hvterm_privs[0] = &hvterm_priv0;
0400
0401
0402 if (of_device_is_compatible(of_stdout, "hvterm1")) {
0403 hvterm_priv0.proto = HV_PROTOCOL_RAW;
0404 ops = &hvterm_raw_ops;
0405 }
0406 else if (of_device_is_compatible(of_stdout, "hvterm-protocol")) {
0407 hvterm_priv0.proto = HV_PROTOCOL_HVSI;
0408 ops = &hvterm_hvsi_ops;
0409 hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars,
0410 hvterm_priv0.termno, 1);
0411
0412 hvsilib_establish(&hvterm_priv0.hvsi);
0413 } else
0414 return;
0415 udbg_putc = udbg_hvc_putc;
0416 udbg_getc = udbg_hvc_getc;
0417 udbg_getc_poll = udbg_hvc_getc_poll;
0418 #ifdef HVC_OLD_HVSI
0419
0420
0421
0422 if (hvterm_priv0.proto == HV_PROTOCOL_HVSI)
0423 return;
0424 #endif
0425
0426 if (!strstr(boot_command_line, "console="))
0427 add_preferred_console("hvc", 0, NULL);
0428 hvc_instantiate(0, 0, ops);
0429 }
0430
0431
0432
0433
0434 #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR
0435 void __init udbg_init_debug_lpar(void)
0436 {
0437
0438
0439
0440
0441
0442 if (mfmsr() & MSR_HV)
0443 return;
0444
0445 hvterm_privs[0] = &hvterm_priv0;
0446 hvterm_priv0.termno = 0;
0447 hvterm_priv0.proto = HV_PROTOCOL_RAW;
0448 spin_lock_init(&hvterm_priv0.buf_lock);
0449 udbg_putc = udbg_hvc_putc;
0450 udbg_getc = udbg_hvc_getc;
0451 udbg_getc_poll = udbg_hvc_getc_poll;
0452 }
0453 #endif
0454
0455 #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR_HVSI
0456 void __init udbg_init_debug_lpar_hvsi(void)
0457 {
0458
0459 if (mfmsr() & MSR_HV)
0460 return;
0461
0462 hvterm_privs[0] = &hvterm_priv0;
0463 hvterm_priv0.termno = CONFIG_PPC_EARLY_DEBUG_HVSI_VTERMNO;
0464 hvterm_priv0.proto = HV_PROTOCOL_HVSI;
0465 spin_lock_init(&hvterm_priv0.buf_lock);
0466 udbg_putc = udbg_hvc_putc;
0467 udbg_getc = udbg_hvc_getc;
0468 udbg_getc_poll = udbg_hvc_getc_poll;
0469 hvsilib_init(&hvterm_priv0.hvsi, hvc_get_chars, hvc_put_chars,
0470 hvterm_priv0.termno, 1);
0471 hvsilib_establish(&hvterm_priv0.hvsi);
0472 }
0473 #endif