11 #define DRV_NAME "bfin-jtag-comm"
12 #define DEV_NAME "ttyBFJC"
13 #define pr_fmt(fmt) DRV_NAME ": " fmt
19 #include <linux/kernel.h>
21 #include <linux/module.h>
23 #include <linux/sched.h>
24 #include <linux/slab.h>
25 #include <linux/tty.h>
30 #define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); })
33 #define EMUDOF 0x00000001
34 #define EMUDIF 0x00000002
35 #define EMUDOOVF 0x00000004
36 #define EMUDIOVF 0x00000008
40 __asm__ __volatile__(
"emudat = %0;" : :
"d"(emudat));
44 static inline uint32_t bfin_read_emudat(
void)
47 __asm__ __volatile__(
"%0 = emudat;" :
"=d"(emudat));
51 static inline uint32_t bfin_write_emudat_chars(
char a,
char b,
char c,
char d)
53 return bfin_write_emudat((a << 0) | (b << 8) | (c << 16) | (d << 24));
56 #define CIRC_SIZE 2048
57 #define CIRC_MASK (CIRC_SIZE - 1)
58 #define circ_empty(circ) ((circ)->head == (circ)->tail)
59 #define circ_free(circ) CIRC_SPACE((circ)->head, (circ)->tail, CIRC_SIZE)
60 #define circ_cnt(circ) CIRC_CNT((circ)->head, (circ)->tail, CIRC_SIZE)
61 #define circ_byte(circ, idx) ((circ)->buf[(idx) & CIRC_MASK])
66 static volatile struct circ_buf bfin_jc_write_buf;
69 bfin_jc_emudat_manager(
void *
arg)
71 uint32_t inbound_len = 0, outbound_len = 0;
86 pr_debug(
"waiting for data (in_len = %i) (circ: %i %i)\n",
87 inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head);
99 uint32_t emudat = bfin_read_emudat();
100 if (inbound_len == 0) {
101 pr_debug(
"incoming length: 0x%08x\n", emudat);
102 inbound_len = emudat;
104 size_t num_chars = (4 <= inbound_len ? 4 : inbound_len);
105 pr_debug(
" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars);
106 inbound_len -= num_chars;
107 tty_insert_flip_string(tty, (
unsigned char *)&emudat, num_chars);
115 if (outbound_len == 0) {
116 outbound_len =
circ_cnt(&bfin_jc_write_buf);
117 bfin_write_emudat(outbound_len);
118 pr_debug(
"outgoing length: 0x%08x\n", outbound_len);
120 int tail = bfin_jc_write_buf.tail;
121 size_t ate = (4 <= outbound_len ? 4 : outbound_len);
123 bfin_write_emudat_chars(
129 bfin_jc_write_buf.tail += ate;
133 pr_debug(
" outgoing data: 0x%08x (pushing %zu)\n", emudat, ate);
150 spin_unlock_irqrestore(&
port.lock, flags);
163 last = --
port.count == 0;
164 spin_unlock_irqrestore(&
port.lock, flags);
172 bfin_jc_circ_write(
const unsigned char *
buf,
int count)
176 pr_debug(
"going to write chunk of %i bytes\n", count);
177 for (i = 0; i <
count; ++
i)
178 circ_byte(&bfin_jc_write_buf, bfin_jc_write_buf.head + i) = buf[
i];
179 bfin_jc_write_buf.head +=
i;
183 #ifndef CONFIG_BFIN_JTAG_COMM_CONSOLE
184 # define console_lock()
185 # define console_unlock()
188 bfin_jc_write(
struct tty_struct *tty,
const unsigned char *buf,
int count)
192 i = bfin_jc_circ_write(buf, count);
211 bfin_jc_chars_in_buffer(
struct tty_struct *tty)
213 return circ_cnt(&bfin_jc_write_buf);
217 bfin_jc_wait_until_sent(
struct tty_struct *tty,
int timeout)
219 unsigned long expire =
jiffies + timeout;
229 .open = bfin_jc_open,
230 .close = bfin_jc_close,
231 .write = bfin_jc_write,
233 .flush_chars = bfin_jc_flush_chars,
234 .write_room = bfin_jc_write_room,
235 .chars_in_buffer = bfin_jc_chars_in_buffer,
236 .wait_until_sent = bfin_jc_wait_until_sent,
239 static int __init bfin_jc_init(
void)
246 if (IS_ERR(bfin_jc_kthread))
247 return PTR_ERR(bfin_jc_kthread);
251 bfin_jc_write_buf.head = bfin_jc_write_buf.tail = 0;
253 if (!bfin_jc_write_buf.buf)
256 bfin_jc_driver = alloc_tty_driver(1);
279 kfree(bfin_jc_write_buf.buf);
286 static void __exit bfin_jc_exit(
void)
289 kfree(bfin_jc_write_buf.buf);
295 #if defined(CONFIG_BFIN_JTAG_COMM_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
297 bfin_jc_straight_buffer_write(
const char *buf,
unsigned count)
302 bfin_write_emudat(count);
303 while (ate < count) {
306 bfin_write_emudat_chars(buf[ate], buf[ate+1], buf[ate+2], buf[ate+3]);
312 #ifdef CONFIG_BFIN_JTAG_COMM_CONSOLE
314 bfin_jc_console_write(
struct console *co,
const char *buf,
unsigned count)
316 if (bfin_jc_kthread ==
NULL)
317 bfin_jc_straight_buffer_write(buf, count);
319 bfin_jc_circ_write(buf, count);
326 return bfin_jc_driver;
329 static struct console bfin_jc_console = {
331 .write = bfin_jc_console_write,
332 .device = bfin_jc_console_device,
337 static int __init bfin_jc_console_init(
void)
345 #ifdef CONFIG_EARLY_PRINTK
347 bfin_jc_early_write(
struct console *co,
const char *buf,
unsigned int count)
349 bfin_jc_straight_buffer_write(buf, count);
353 .
name =
"early_BFJC",
354 .write = bfin_jc_early_write,
360 bfin_jc_early_init(
unsigned int port,
unsigned int cflag)
362 return &bfin_jc_early_console;