From e32f23af9b2c695b56e06bc07ce482c3ae8c126f Mon Sep 17 00:00:00 2001 From: Miroslav Ondra Date: Wed, 22 Jan 2020 21:57:22 +0100 Subject: [PATCH] Add flush_buffer to uart --- modules/unipi/src/unipi_common.h | 1 + modules/unipi/src/unipi_spi.c | 4 +-- modules/unipi/src/unipi_uart.c | 42 +++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/modules/unipi/src/unipi_common.h b/modules/unipi/src/unipi_common.h index edb0848..0196f87 100644 --- a/modules/unipi/src/unipi_common.h +++ b/modules/unipi/src/unipi_common.h @@ -126,6 +126,7 @@ struct neuronspi_port u8 rx_remain; int accept_rx; + struct kthread_work flush_work; struct kthread_work tx_work; u16 tx_fifo_reg; // register in neuronspi device modbus map to read internal tx fifo length diff --git a/modules/unipi/src/unipi_spi.c b/modules/unipi/src/unipi_spi.c index ad1bdbf..6fa32e3 100644 --- a/modules/unipi/src/unipi_spi.c +++ b/modules/unipi/src/unipi_spi.c @@ -430,7 +430,7 @@ static void unipi_spi_read_str_complete(void *arg) port = unipi_spi_check_message(context); context->string_op_port->rx_in_progress = 0; - + if (recv_buf->second_message[0] == 0x65) { // this op can be invoked only from kernel_work rx_proc portindex2 = 0; // second_message[2]; Overit ve firmware @@ -446,7 +446,7 @@ static void unipi_spi_read_str_complete(void *arg) } if (port && (port->rx_remain)) unipi_spi_read_str(context->message.spi, port); - + kfree(context); } diff --git a/modules/unipi/src/unipi_uart.c b/modules/unipi/src/unipi_uart.c index 6d04b03..7837586 100644 --- a/modules/unipi/src/unipi_uart.c +++ b/modules/unipi/src/unipi_uart.c @@ -153,13 +153,46 @@ void neuronspi_uart_set_ldisc(struct uart_port *port, struct ktermios *kterm) unipispi_modbus_write_register(spi, port_to_uartregs(n_port->dev_port, NEURONSPI_UART_LDISC_REGISTER), kterm->c_line); } + +void neuronspi_uart_flush_proc(struct kthread_work *ws) +{ + struct neuronspi_port *n_port = ((container_of((ws), struct neuronspi_port, flush_work))); + struct spi_device *spi = neuronspi_s_dev[n_spi->neuron_index]; + struct neuronspi_op_buffer recv_buf; + unsigned long flags; + + unipi_spi_read_str(spi, n_port); + if (n_port->rx_in_progress) { + s32 frequency = NEURONSPI_DEFAULT_FREQ; + if (n_spi) { + frequency = n_spi->ideal_frequency; + } + neuronspi_spi_send_const_op(spi, &UNIPISPI_IDLE_MESSAGE, &recv_buf, 0, frequency, 25); + } + + spin_lock_irqsave(&port->port.lock, flags); + n_port->accept_rx = 1; + spin_lock_irqrestore(&port->port.lock, flags); + +} + + void neuronspi_uart_flush_buffer(struct uart_port* port) { + struct neuronspi_port *n_port = to_neuronspi_port(port, port); + struct neuronspi_driver_data *n_spi = n_port->n_spi; + #struct spi_device *spi = neuronspi_s_dev[n_port->dev_index]; + #struct neuronspi_driver_data *n_spi = spi_get_drvdata(spi); + //port->lock taken, This call must not sleep - // ToDo : unipi_uart_trace("ttyNS%d Flush buffer\n", port->line); + n_port->accept_rx = 0; + unipi_spi_trace(KERN_INFO "UNIPISPI: nspi%d SPI IRQ\n", n_spi->neuron_index); + kthread_queue_work(n_spi->primary_worker, &n_port->flush_work); + //unipi_spi_idle_op(spi); } + u32 neuronspi_uart_tx_empty(struct uart_port *port) { struct neuronspi_port *n_port = to_neuronspi_port(port, port); @@ -601,7 +634,7 @@ void neuronspi_uart_remove(struct spi_device* spi) struct neuronspi_driver_data *n_spi = spi_get_drvdata(spi); struct neuronspi_port *port; int i, uart_count; - + uart_count = n_spi->uart_count; n_spi->uart_count = 0; @@ -675,7 +708,7 @@ int neuronspi_uart_probe(struct spi_device* spi, struct neuronspi_driver_data *n spin_lock_init(&port->txop_lock); port->tx_send_buf.second_message = port->tx_send_msg; port->tx_recv_buf.second_message = port->tx_recv_msg; - + port->tx_fifo_len = 0x7fff; //set it to big number; invoke reading current value from Neuron if (n_spi && (n_spi->firmware_version >= 0x0519) ) { port->tx_fifo_reg = port_to_uartregs(i,NEURONSPI_UART_FIFO_REGISTER); // define modbus register @@ -685,8 +718,9 @@ int neuronspi_uart_probe(struct spi_device* spi, struct neuronspi_driver_data *n hrtimer_init(&port->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); port->tx_timer.function = unipi_uart_timer_func; - + //kthread_init_work(&(port->tx_work), neuronspi_uart_tx_proc); + kthread_init_work(&(port->flush_work), neuronspi_flush_proc); // prepare work function for port flushing uart_add_one_port(neuronspi_uart_driver_global, &port->port); printk(KERN_INFO "UNIPIUART: Serial port ttyNS%d on UniPi Board nspi%d port:%d created\n", neuronspi_uart_data_global->p_count, port->dev_index, port->dev_port); unipi_uart_trace("Probe cflag:%08x\n", neuronspi_spi_uart_get_cflag(spi, i)); -- 2.34.1