Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Mike Frysinger and committed by
Greg Kroah-Hartman
5427bcf5 9fc3de9c

+115
+9
drivers/char/Kconfig
··· 691 691 driver. This console is used through a JTAG only on ARM. If you don't have 692 692 a JTAG then you probably don't want this option. 693 693 694 + config HVC_BFIN_JTAG 695 + bool "Blackfin JTAG console" 696 + depends on BLACKFIN 697 + select HVC_DRIVER 698 + help 699 + This console uses the Blackfin JTAG to create a console under the 700 + the HVC driver. If you don't have JTAG, then you probably don't 701 + want this option. 702 + 694 703 config VIRTIO_CONSOLE 695 704 tristate "Virtio console" 696 705 depends on VIRTIO
+1
drivers/tty/hvc/Makefile
··· 9 9 obj-$(CONFIG_HVC_XEN) += hvc_xen.o 10 10 obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o 11 11 obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o 12 + obj-$(CONFIG_HVC_BFIN_JTAG) += hvc_bfin_jtag.o 12 13 obj-$(CONFIG_HVCS) += hvcs.o 13 14 obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
+105
drivers/tty/hvc/hvc_bfin_jtag.c
··· 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 */ 27 + static inline uint32_t bfin_write_emudat(uint32_t emudat) 28 + { 29 + __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); 30 + return emudat; 31 + } 32 + 33 + static 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 */ 41 + static 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 */ 65 + static 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 */ 88 + static 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 + 93 + static int __init hvc_bfin_console_init(void) 94 + { 95 + hvc_instantiate(0, 0, &hvc_bfin_get_put_ops); 96 + return 0; 97 + } 98 + console_initcall(hvc_bfin_console_init); 99 + 100 + static int __init hvc_bfin_init(void) 101 + { 102 + hvc_alloc(0, 0, &hvc_bfin_get_put_ops, 128); 103 + return 0; 104 + } 105 + device_initcall(hvc_bfin_init);