-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Mike Frysinger
authored and
Greg Kroah-Hartman
committed
Feb 17, 2011
1 parent
9fc3de9
commit 5427bcf
Showing
3 changed files
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* Console via Blackfin JTAG Communication | ||
* | ||
* Copyright 2008-2011 Analog Devices Inc. | ||
* | ||
* Enter bugs at http://blackfin.uclinux.org/ | ||
* | ||
* Licensed under the GPL-2 or later. | ||
*/ | ||
|
||
#include <linux/console.h> | ||
#include <linux/delay.h> | ||
#include <linux/err.h> | ||
#include <linux/init.h> | ||
#include <linux/moduleparam.h> | ||
#include <linux/types.h> | ||
|
||
#include "hvc_console.h" | ||
|
||
/* See the Debug/Emulation chapter in the HRM */ | ||
#define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */ | ||
#define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */ | ||
#define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */ | ||
#define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */ | ||
|
||
/* Helper functions to glue the register API to simple C operations */ | ||
static inline uint32_t bfin_write_emudat(uint32_t emudat) | ||
{ | ||
__asm__ __volatile__("emudat = %0;" : : "d"(emudat)); | ||
return emudat; | ||
} | ||
|
||
static inline uint32_t bfin_read_emudat(void) | ||
{ | ||
uint32_t emudat; | ||
__asm__ __volatile__("%0 = emudat;" : "=d"(emudat)); | ||
return emudat; | ||
} | ||
|
||
/* Send data to the host */ | ||
static int hvc_bfin_put_chars(uint32_t vt, const char *buf, int count) | ||
{ | ||
static uint32_t outbound_len; | ||
uint32_t emudat; | ||
int ret; | ||
|
||
if (bfin_read_DBGSTAT() & EMUDOF) | ||
return 0; | ||
|
||
if (!outbound_len) { | ||
outbound_len = count; | ||
bfin_write_emudat(outbound_len); | ||
return 0; | ||
} | ||
|
||
ret = min(outbound_len, (uint32_t)4); | ||
memcpy(&emudat, buf, ret); | ||
bfin_write_emudat(emudat); | ||
outbound_len -= ret; | ||
|
||
return ret; | ||
} | ||
|
||
/* Receive data from the host */ | ||
static int hvc_bfin_get_chars(uint32_t vt, char *buf, int count) | ||
{ | ||
static uint32_t inbound_len; | ||
uint32_t emudat; | ||
int ret; | ||
|
||
if (!(bfin_read_DBGSTAT() & EMUDIF)) | ||
return 0; | ||
emudat = bfin_read_emudat(); | ||
|
||
if (!inbound_len) { | ||
inbound_len = emudat; | ||
return 0; | ||
} | ||
|
||
ret = min(inbound_len, (uint32_t)4); | ||
memcpy(buf, &emudat, ret); | ||
inbound_len -= ret; | ||
|
||
return ret; | ||
} | ||
|
||
/* Glue the HVC layers to the Blackfin layers */ | ||
static const struct hv_ops hvc_bfin_get_put_ops = { | ||
.get_chars = hvc_bfin_get_chars, | ||
.put_chars = hvc_bfin_put_chars, | ||
}; | ||
|
||
static int __init hvc_bfin_console_init(void) | ||
{ | ||
hvc_instantiate(0, 0, &hvc_bfin_get_put_ops); | ||
return 0; | ||
} | ||
console_initcall(hvc_bfin_console_init); | ||
|
||
static int __init hvc_bfin_init(void) | ||
{ | ||
hvc_alloc(0, 0, &hvc_bfin_get_put_ops, 128); | ||
return 0; | ||
} | ||
device_initcall(hvc_bfin_init); |