aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-02-04 20:45:49 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-02-17 14:12:40 -0500
commit5427bcf5e95245d3e220742ac703182bdb973769 (patch)
tree6eed2090099d98a4bec5d150b3d0c5ee8e1b9354 /drivers/tty/hvc
parent9fc3de9c83565fcaa23df74c2fc414bb6e7efb0a (diff)
hvc: add Blackfin JTAG console support
This converts the existing bfin_jtag_comm TTY driver to the HVC layer so that the common HVC code can worry about all of the TTY/polling crap and leave the Blackfin code to worry about the Blackfin bits. Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/Makefile1
-rw-r--r--drivers/tty/hvc/hvc_bfin_jtag.c105
2 files changed, 106 insertions, 0 deletions
diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile
index e6bed5f177ff..7b0edbce9009 100644
--- a/drivers/tty/hvc/Makefile
+++ b/drivers/tty/hvc/Makefile
@@ -9,5 +9,6 @@ obj-$(CONFIG_HVC_IRQ) += hvc_irq.o
9obj-$(CONFIG_HVC_XEN) += hvc_xen.o 9obj-$(CONFIG_HVC_XEN) += hvc_xen.o
10obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o 10obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o
11obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o 11obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o
12obj-$(CONFIG_HVC_BFIN_JTAG) += hvc_bfin_jtag.o
12obj-$(CONFIG_HVCS) += hvcs.o 13obj-$(CONFIG_HVCS) += hvcs.o
13obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o 14obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
diff --git a/drivers/tty/hvc/hvc_bfin_jtag.c b/drivers/tty/hvc/hvc_bfin_jtag.c
new file mode 100644
index 000000000000..31d6cc6a77af
--- /dev/null
+++ b/drivers/tty/hvc/hvc_bfin_jtag.c
@@ -0,0 +1,105 @@
1/*
2 * Console via Blackfin JTAG Communication
3 *
4 * Copyright 2008-2011 Analog Devices Inc.
5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/console.h>
12#include <linux/delay.h>
13#include <linux/err.h>
14#include <linux/init.h>
15#include <linux/moduleparam.h>
16#include <linux/types.h>
17
18#include "hvc_console.h"
19
20/* See the Debug/Emulation chapter in the HRM */
21#define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */
22#define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */
23#define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */
24#define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */
25
26/* Helper functions to glue the register API to simple C operations */
27static inline uint32_t bfin_write_emudat(uint32_t emudat)
28{
29 __asm__ __volatile__("emudat = %0;" : : "d"(emudat));
30 return emudat;
31}
32
33static inline uint32_t bfin_read_emudat(void)
34{
35 uint32_t emudat;
36 __asm__ __volatile__("%0 = emudat;" : "=d"(emudat));
37 return emudat;
38}
39
40/* Send data to the host */
41static int hvc_bfin_put_chars(uint32_t vt, const char *buf, int count)
42{
43 static uint32_t outbound_len;
44 uint32_t emudat;
45 int ret;
46
47 if (bfin_read_DBGSTAT() & EMUDOF)
48 return 0;
49
50 if (!outbound_len) {
51 outbound_len = count;
52 bfin_write_emudat(outbound_len);
53 return 0;
54 }
55
56 ret = min(outbound_len, (uint32_t)4);
57 memcpy(&emudat, buf, ret);
58 bfin_write_emudat(emudat);
59 outbound_len -= ret;
60
61 return ret;
62}
63
64/* Receive data from the host */
65static int hvc_bfin_get_chars(uint32_t vt, char *buf, int count)
66{
67 static uint32_t inbound_len;
68 uint32_t emudat;
69 int ret;
70
71 if (!(bfin_read_DBGSTAT() & EMUDIF))
72 return 0;
73 emudat = bfin_read_emudat();
74
75 if (!inbound_len) {
76 inbound_len = emudat;
77 return 0;
78 }
79
80 ret = min(inbound_len, (uint32_t)4);
81 memcpy(buf, &emudat, ret);
82 inbound_len -= ret;
83
84 return ret;
85}
86
87/* Glue the HVC layers to the Blackfin layers */
88static const struct hv_ops hvc_bfin_get_put_ops = {
89 .get_chars = hvc_bfin_get_chars,
90 .put_chars = hvc_bfin_put_chars,
91};
92
93static int __init hvc_bfin_console_init(void)
94{
95 hvc_instantiate(0, 0, &hvc_bfin_get_put_ops);
96 return 0;
97}
98console_initcall(hvc_bfin_console_init);
99
100static int __init hvc_bfin_init(void)
101{
102 hvc_alloc(0, 0, &hvc_bfin_get_put_ops, 128);
103 return 0;
104}
105device_initcall(hvc_bfin_init);