Commit e63f9f74 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

TTY: bfin_jtag_comm, use tty from tty_port

Switch from mutex to tty_port->lock and to tty refcounting. This needs
a 'continue' to be added to re-grab a tty after schedule returns.

And since tty is not protected by bfin_jc_tty_mutex remove it as well.
But this needs tty_port->count to be protected by tty_port->lock now.
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: uclinux-dist-devel@blackfin.uclinux.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 560460b8
...@@ -62,8 +62,6 @@ static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d) ...@@ -62,8 +62,6 @@ static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d)
static struct tty_driver *bfin_jc_driver; static struct tty_driver *bfin_jc_driver;
static struct task_struct *bfin_jc_kthread; static struct task_struct *bfin_jc_kthread;
static struct tty_struct * volatile bfin_jc_tty;
static DEFINE_MUTEX(bfin_jc_tty_mutex);
static struct tty_port port; static struct tty_port port;
static volatile struct circ_buf bfin_jc_write_buf; static volatile struct circ_buf bfin_jc_write_buf;
...@@ -73,18 +71,21 @@ bfin_jc_emudat_manager(void *arg) ...@@ -73,18 +71,21 @@ bfin_jc_emudat_manager(void *arg)
uint32_t inbound_len = 0, outbound_len = 0; uint32_t inbound_len = 0, outbound_len = 0;
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
struct tty_struct *tty = tty_port_tty_get(&port);
/* no one left to give data to, so sleep */ /* no one left to give data to, so sleep */
if (bfin_jc_tty == NULL && circ_empty(&bfin_jc_write_buf)) { if (tty == NULL && circ_empty(&bfin_jc_write_buf)) {
pr_debug("waiting for readers\n"); pr_debug("waiting for readers\n");
__set_current_state(TASK_UNINTERRUPTIBLE); __set_current_state(TASK_UNINTERRUPTIBLE);
schedule(); schedule();
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
continue;
} }
/* no data available, so just chill */ /* no data available, so just chill */
if (!(bfin_read_DBGSTAT() & EMUDIF) && circ_empty(&bfin_jc_write_buf)) { if (!(bfin_read_DBGSTAT() & EMUDIF) && circ_empty(&bfin_jc_write_buf)) {
pr_debug("waiting for data (in_len = %i) (circ: %i %i)\n", pr_debug("waiting for data (in_len = %i) (circ: %i %i)\n",
inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head); inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head);
tty_kref_put(tty);
if (inbound_len) if (inbound_len)
schedule(); schedule();
else else
...@@ -94,9 +95,6 @@ bfin_jc_emudat_manager(void *arg) ...@@ -94,9 +95,6 @@ bfin_jc_emudat_manager(void *arg)
/* if incoming data is ready, eat it */ /* if incoming data is ready, eat it */
if (bfin_read_DBGSTAT() & EMUDIF) { if (bfin_read_DBGSTAT() & EMUDIF) {
struct tty_struct *tty;
mutex_lock(&bfin_jc_tty_mutex);
tty = (struct tty_struct *)bfin_jc_tty;
if (tty != NULL) { if (tty != NULL) {
uint32_t emudat = bfin_read_emudat(); uint32_t emudat = bfin_read_emudat();
if (inbound_len == 0) { if (inbound_len == 0) {
...@@ -110,7 +108,6 @@ bfin_jc_emudat_manager(void *arg) ...@@ -110,7 +108,6 @@ bfin_jc_emudat_manager(void *arg)
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
} }
} }
mutex_unlock(&bfin_jc_tty_mutex);
} }
/* if outgoing data is ready, post it */ /* if outgoing data is ready, post it */
...@@ -120,7 +117,6 @@ bfin_jc_emudat_manager(void *arg) ...@@ -120,7 +117,6 @@ bfin_jc_emudat_manager(void *arg)
bfin_write_emudat(outbound_len); bfin_write_emudat(outbound_len);
pr_debug("outgoing length: 0x%08x\n", outbound_len); pr_debug("outgoing length: 0x%08x\n", outbound_len);
} else { } else {
struct tty_struct *tty;
int tail = bfin_jc_write_buf.tail; int tail = bfin_jc_write_buf.tail;
size_t ate = (4 <= outbound_len ? 4 : outbound_len); size_t ate = (4 <= outbound_len ? 4 : outbound_len);
uint32_t emudat = uint32_t emudat =
...@@ -132,14 +128,12 @@ bfin_jc_emudat_manager(void *arg) ...@@ -132,14 +128,12 @@ bfin_jc_emudat_manager(void *arg)
); );
bfin_jc_write_buf.tail += ate; bfin_jc_write_buf.tail += ate;
outbound_len -= ate; outbound_len -= ate;
mutex_lock(&bfin_jc_tty_mutex);
tty = (struct tty_struct *)bfin_jc_tty;
if (tty) if (tty)
tty_wakeup(tty); tty_wakeup(tty);
mutex_unlock(&bfin_jc_tty_mutex);
pr_debug(" outgoing data: 0x%08x (pushing %zu)\n", emudat, ate); pr_debug(" outgoing data: 0x%08x (pushing %zu)\n", emudat, ate);
} }
} }
tty_kref_put(tty);
} }
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
...@@ -149,22 +143,28 @@ bfin_jc_emudat_manager(void *arg) ...@@ -149,22 +143,28 @@ bfin_jc_emudat_manager(void *arg)
static int static int
bfin_jc_open(struct tty_struct *tty, struct file *filp) bfin_jc_open(struct tty_struct *tty, struct file *filp)
{ {
mutex_lock(&bfin_jc_tty_mutex); unsigned long flags;
spin_lock_irqsave(&port.lock, flags);
port.count++; port.count++;
bfin_jc_tty = tty; spin_unlock_irqrestore(&port.lock, flags);
tty_port_tty_set(&port, tty);
wake_up_process(bfin_jc_kthread); wake_up_process(bfin_jc_kthread);
mutex_unlock(&bfin_jc_tty_mutex);
return 0; return 0;
} }
static void static void
bfin_jc_close(struct tty_struct *tty, struct file *filp) bfin_jc_close(struct tty_struct *tty, struct file *filp)
{ {
mutex_lock(&bfin_jc_tty_mutex); unsigned long flags;
if (--port.count == 0) bool last;
bfin_jc_tty = NULL;
spin_lock_irqsave(&port.lock, flags);
last = --port.count == 0;
spin_unlock_irqrestore(&port.lock, flags);
if (last)
tty_port_tty_set(&port, NULL);
wake_up_process(bfin_jc_kthread); wake_up_process(bfin_jc_kthread);
mutex_unlock(&bfin_jc_tty_mutex);
} }
/* XXX: we dont handle the put_char() case where we must handle count = 1 */ /* XXX: we dont handle the put_char() case where we must handle count = 1 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment