From f315fde358c711881ed1675479d53724bf971550 Mon Sep 17 00:00:00 2001 From: Tom Knot Date: Wed, 27 Jun 2018 15:24:18 +0200 Subject: [PATCH] Added interrupt saving for all spinlocks --- modules/unipi/src/unipi_misc.c | 5 ++-- modules/unipi/src/unipi_spi.c | 14 +++++---- modules/unipi/src/unipi_sysfs.c | 35 ++++++++++++++--------- modules/unipi/src/unipi_uart.c | 50 +++++++++++++++++---------------- version.txt | 2 +- 5 files changed, 59 insertions(+), 47 deletions(-) diff --git a/modules/unipi/src/unipi_misc.c b/modules/unipi/src/unipi_misc.c index ae9eba0..c17c287 100644 --- a/modules/unipi/src/unipi_misc.c +++ b/modules/unipi/src/unipi_misc.c @@ -33,8 +33,9 @@ void neuronspi_led_set_brightness(struct led_classdev *ldev, enum led_brightness { struct neuronspi_led_driver *led = container_of(ldev, struct neuronspi_led_driver, ldev); struct neuronspi_driver_data *n_spi = spi_get_drvdata(led->spi); - spin_lock(&led->lock); + unsigned long flags; + spin_lock_irqsave(&led->lock, flags); led->brightness = brightness; kthread_queue_work(&n_spi->primary_worker, &led->led_work); - spin_unlock(&led->lock); + spin_unlock_irqrestore(&led->lock, flags); } diff --git a/modules/unipi/src/unipi_spi.c b/modules/unipi/src/unipi_spi.c index 17f4d35..9277b19 100644 --- a/modules/unipi/src/unipi_spi.c +++ b/modules/unipi/src/unipi_spi.c @@ -178,6 +178,7 @@ ssize_t neuronspi_write (struct file *file_p, const char *buffer, size_t len, lo s32 transmit_len = len - NEURONSPI_HEADER_LENGTH; s32 send_header = 0; s32 delay = 25; + unsigned long flags; struct neuronspi_file_data* private_data; struct spi_device* spi_driver_data; struct neuronspi_driver_data* driver_data; @@ -247,9 +248,9 @@ ssize_t neuronspi_write (struct file *file_p, const char *buffer, size_t len, lo memcpy(private_data->send_buf, buffer, len); memset(private_data->recv_buf, 0, NEURONSPI_BUFFER_MAX ); private_data->message_len = transmit_len; - spin_lock(neuronspi_spi_w_spinlock); + spin_lock_irqsave(neuronspi_spi_w_spinlock, flags); neuronspi_spi_w_flag = 1; - spin_unlock(neuronspi_spi_w_spinlock); + spin_unlock_irqrestore(neuronspi_spi_w_spinlock, flags); neuronspi_spi_send_message(spi_driver_data, &private_data->send_buf[NEURONSPI_HEADER_LENGTH], private_data->recv_buf, transmit_len, frequency, delay, send_header, buffer[7]); mutex_unlock(&private_data->lock); @@ -900,10 +901,11 @@ s32 neuronspi_spi_probe(struct spi_device *spi) struct neuronspi_driver_data *n_spi; s32 ret, i, no_irq = 0; u8 uart_count = 0; + unsigned long flags; n_spi = kzalloc(sizeof *n_spi, GFP_ATOMIC); - spin_lock(neuronspi_probe_spinlock); + spin_lock_irqsave(neuronspi_probe_spinlock, flags); neuronspi_probe_count++; - spin_unlock(neuronspi_probe_spinlock); + spin_unlock_irqrestore(neuronspi_probe_spinlock, flags); if (!n_spi) return -ENOMEM; printk(KERN_INFO "NEURONSPI: Neuronspi Probe Started\n"); @@ -1109,13 +1111,13 @@ reg1001: %x, reg1002: %x, reg1003: %x, reg1004: %x\n", #if NEURONSPI_DETAILED_DEBUG > 0 printk(KERN_DEBUG "NEURONSPI: CHIP SELECT %d\n", spi->chip_select); #endif - spin_lock(neuronspi_probe_spinlock); + spin_lock_irqsave(neuronspi_probe_spinlock, flags); neuronspi_s_dev[n_spi->neuron_index] = spi; spi_set_drvdata(neuronspi_s_dev[n_spi->neuron_index], n_spi); if (neuronspi_probe_count == NEURONSPI_MAX_DEVS) { neuronspi_model_id = neuronspi_find_model_id(neuronspi_probe_count); } - spin_unlock(neuronspi_probe_spinlock); + spin_unlock_irqrestore(neuronspi_probe_spinlock, flags); if (neuronspi_model_id != -1) { printk(KERN_INFO "NEURONSPI: Detected Neuron board combination corresponding to %s\n", NEURONSPI_MODELTABLE[neuronspi_model_id].model_name); } diff --git a/modules/unipi/src/unipi_sysfs.c b/modules/unipi/src/unipi_sysfs.c index ff49a1f..0a03e9e 100644 --- a/modules/unipi/src/unipi_sysfs.c +++ b/modules/unipi/src/unipi_sysfs.c @@ -713,15 +713,16 @@ static ssize_t neuronspi_spi_show_register(struct device *dev, struct device_att int read_length; ssize_t ret = 0; u16 val = 0; + unsigned long flags; struct neuronspi_driver_data *n_spi; struct spi_device *spi; struct platform_device *plat = to_platform_device(dev); n_spi = platform_get_drvdata(plat); spi = neuronspi_s_dev[n_spi->neuron_index]; if (n_spi && n_spi->reg_map) { - spin_lock(&n_spi->sysfs_regmap_lock); + spin_lock_irqsave(&n_spi->sysfs_regmap_lock, flags); read_length = neuronspi_spi_compose_single_register_read(n_spi->sysfs_register_target, &inp_buf, &outp_buf); - spin_unlock(&n_spi->sysfs_regmap_lock); + spin_unlock_irqrestore(&n_spi->sysfs_regmap_lock, flags); neuronspi_spi_send_message(spi, inp_buf, outp_buf, read_length, n_spi->ideal_frequency, 125, 1, 0); memcpy(&val, &outp_buf[NEURONSPI_HEADER_LENGTH], sizeof(u16)); ret = scnprintf(buf, 255, "%x\n", (u32)val); @@ -733,15 +734,16 @@ static ssize_t neuronspi_spi_store_register(struct device *dev, struct device_at { ssize_t err = 0; unsigned int val = 0; + unsigned long flags; struct neuronspi_driver_data *n_spi; struct platform_device *plat = to_platform_device(dev); n_spi = platform_get_drvdata(plat); err = kstrtouint(buf, 0, &val); if (err < 0) goto err_end; if (n_spi && n_spi->reg_map && val < 65536) { - spin_lock(&n_spi->sysfs_regmap_lock); + spin_lock_irqsave(&n_spi->sysfs_regmap_lock, flags); n_spi->sysfs_register_target = val; - spin_unlock(&n_spi->sysfs_regmap_lock); + spin_unlock_irqrestore(&n_spi->sysfs_regmap_lock, flags); } err_end: return count; @@ -753,6 +755,7 @@ static ssize_t neuronspi_spi_store_register_value(struct device *dev, struct dev int write_length; ssize_t err = 0; unsigned int val = 0; + unsigned long flags; struct neuronspi_driver_data *n_spi; struct spi_device *spi; struct platform_device *plat = to_platform_device(dev); @@ -761,9 +764,9 @@ static ssize_t neuronspi_spi_store_register_value(struct device *dev, struct dev err = kstrtouint(buf, 0, &val); if (err < 0) goto err_end; if (n_spi && n_spi->reg_map && val < 65536) { - spin_lock(&n_spi->sysfs_regmap_lock); + spin_lock_irqsave(&n_spi->sysfs_regmap_lock, flags); write_length = neuronspi_spi_compose_single_register_read(n_spi->sysfs_register_target, &inp_buf, &outp_buf); - spin_unlock(&n_spi->sysfs_regmap_lock); + spin_unlock_irqrestore(&n_spi->sysfs_regmap_lock, flags); neuronspi_spi_send_message(spi, inp_buf, outp_buf, write_length, n_spi->ideal_frequency, 125, 1, 0); } err_end: @@ -776,16 +779,17 @@ static ssize_t neuronspi_show_regmap(struct device *dev, struct device_attribute { ssize_t ret = 0; u32 val = 0; + unsigned long flags; struct neuronspi_driver_data *n_spi; struct spi_device *spi; struct platform_device *plat = to_platform_device(dev); n_spi = platform_get_drvdata(plat); spi = neuronspi_s_dev[n_spi->neuron_index]; if (n_spi && n_spi->reg_map) { - spin_lock(&n_spi->sysfs_regmap_lock); + spin_lock_irqsave(&n_spi->sysfs_regmap_lock, flags); regmap_read(n_spi->reg_map, n_spi->sysfs_regmap_target, &val); ret = scnprintf(buf, 255, "%x\n", val); - spin_unlock(&n_spi->sysfs_regmap_lock); + spin_unlock_irqrestore(&n_spi->sysfs_regmap_lock, flags); } return ret; } @@ -794,15 +798,16 @@ static ssize_t neuronspi_store_regmap(struct device *dev, struct device_attribut { ssize_t err = 0; unsigned int val = 0; + unsigned long flags; struct neuronspi_driver_data *n_spi; struct platform_device *plat = to_platform_device(dev); n_spi = platform_get_drvdata(plat); err = kstrtouint(buf, 0, &val); if (err < 0) goto err_end; if (n_spi && n_spi->reg_map && val < 65536) { - spin_lock(&n_spi->sysfs_regmap_lock); + spin_lock_irqsave(&n_spi->sysfs_regmap_lock, flags); n_spi->sysfs_regmap_target = val; - spin_unlock(&n_spi->sysfs_regmap_lock); + spin_unlock_irqrestore(&n_spi->sysfs_regmap_lock, flags); } err_end: return count; @@ -812,15 +817,16 @@ static ssize_t neuronspi_store_regmap_value(struct device *dev, struct device_at { ssize_t err = 0; unsigned int val = 0; + unsigned long flags; struct neuronspi_driver_data *n_spi; struct platform_device *plat = to_platform_device(dev); n_spi = platform_get_drvdata(plat); err = kstrtouint(buf, 0, &val); if (err < 0) goto err_end; if (n_spi && n_spi->reg_map && val < 65536) { - spin_lock(&n_spi->sysfs_regmap_lock); + spin_lock_irqsave(&n_spi->sysfs_regmap_lock, flags); regmap_write(n_spi->reg_map, n_spi->sysfs_regmap_target, val); - spin_unlock(&n_spi->sysfs_regmap_lock); + spin_unlock_irqrestore(&n_spi->sysfs_regmap_lock, flags); } err_end: return count; @@ -963,15 +969,16 @@ static ssize_t neuronspi_spi_gpio_show_do_count(struct device *dev, struct devic static ssize_t neuronspi_spi_gpio_show_di_count(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret = 0; + unsigned long flags; struct neuronspi_di_driver *n_di; struct neuronspi_driver_data *n_spi; struct platform_device *plat = to_platform_device(dev); n_di = platform_get_drvdata(plat); n_spi = spi_get_drvdata(n_di->spi); if (n_spi->features && n_spi->features->di_count > 0 && n_spi->di_driver) { - spin_lock(&n_spi->sysfs_regmap_lock); + spin_lock_irqsave(&n_spi->sysfs_regmap_lock, flags); ret = scnprintf(buf, 255, "%d\n", n_spi->di_driver[n_di->di_index]->gpio_c.ngpio); - spin_unlock(&n_spi->sysfs_regmap_lock); + spin_unlock_irqrestore(&n_spi->sysfs_regmap_lock, flags); } return ret; } diff --git a/modules/unipi/src/unipi_uart.c b/modules/unipi/src/unipi_uart.c index 52a0ac0..f1c7746 100644 --- a/modules/unipi/src/unipi_uart.c +++ b/modules/unipi/src/unipi_uart.c @@ -294,39 +294,40 @@ void neuronspi_uart_handle_rx(struct neuronspi_port *port, u32 rxlen, u32 iir) void neuronspi_uart_handle_tx(struct neuronspi_port *port) { u32 max_txlen, to_send, to_send_packet, i; + unsigned long flags; struct spi_device *spi; struct neuronspi_driver_data *d_data; struct circ_buf *xmit; spi = neuronspi_s_dev[port->dev_index]; d_data = spi_get_drvdata(spi); - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); xmit = &port->port.state->xmit; - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); if (unlikely(port->port.x_char)) { neuronspi_spi_uart_write(spi, &port->port.x_char, 1, port->dev_port); - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); port->port.icount.tx++; - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); port->port.x_char = 0; - spin_lock(&port->tx_lock); + spin_lock_irqsave(&port->tx_lock, flags); port->tx_work_count--; - spin_unlock(&port->tx_lock); + spin_unlock_irqrestore(&port->tx_lock, flags); return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&port->port)) { - spin_lock(&port->tx_lock); + spin_lock_irqsave(&port->tx_lock, flags); port->tx_work_count--; - spin_unlock(&port->tx_lock); + spin_unlock_irqrestore(&port->tx_lock, flags); return; } /* Get length of data pending in circular buffer */ - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); to_send = uart_circ_chars_pending(xmit); - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); printk(KERN_INFO "NEURONSPI UART_HANDLE_TX A, to_send:%d, tx_work_count:%d\n", to_send, port->tx_work_count); if (likely(to_send)) { /* Limit to size of (TX FIFO / 2) */ @@ -335,16 +336,16 @@ void neuronspi_uart_handle_tx(struct neuronspi_port *port) to_send_packet = (to_send > max_txlen) ? max_txlen : to_send; /* Add data to send */ - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); port->port.icount.tx += to_send_packet; - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); /* Convert to linear buffer */ for (i = 0; i < to_send_packet; ++i) { - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); port->buf[i] = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); } printk(KERN_INFO "NEURONSPI UART_HANDLE_TX B, to_send:%d, tx_work_count:%d\n", to_send_packet, port->tx_work_count); neuronspi_uart_fifo_write(port, to_send_packet); @@ -353,29 +354,29 @@ void neuronspi_uart_handle_tx(struct neuronspi_port *port) to_send = (to_send > NEURONSPI_FIFO_SIZE - NEURONSPI_FIFO_MIN_CONTINUOUS) ? NEURONSPI_FIFO_SIZE - NEURONSPI_FIFO_MIN_CONTINUOUS : to_send; /* Add data to send */ - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); port->port.icount.tx += to_send; - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); /* Convert to linear buffer */ for (i = 0; i < to_send; ++i) { - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); port->buf[i] = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); } printk(KERN_INFO "NEURONSPI UART_HANDLE_TX C, to_send:%d, tx_work_count:%d\n", to_send, port->tx_work_count); neuronspi_uart_fifo_write(port, to_send); } - spin_lock(&port->tx_lock); + spin_lock_irqsave(&port->tx_lock, flags); port->tx_work_count--; - spin_unlock(&port->tx_lock); + spin_unlock_irqrestore(&port->tx_lock, flags); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { - spin_lock(&port->port.lock); + spin_lock_irqsave(&port->port.lock, flags); uart_write_wakeup(&port->port); - spin_unlock(&port->port.lock); + spin_unlock_irqrestore(&port->port.lock, flags); } } @@ -586,10 +587,11 @@ void neuronspi_uart_rx_proc(struct kthread_work *ws) void neuronspi_uart_start_tx(struct uart_port *port) { struct neuronspi_port *n_port = to_neuronspi_port(port,port); + unsigned long flags; #if NEURONSPI_DETAILED_DEBUG > 0 printk(KERN_INFO "NEURONSPI: Start TX\n"); #endif - spin_lock(&n_port->tx_lock); + spin_lock_irqsave(&n_port->tx_lock, flags); if (n_port->tx_work_count > NEURONSPI_MAX_TX_WORK) { spin_unlock(&n_port->tx_lock); printk(KERN_INFO "NEURONSPI: TX WORK OVERFLOW\n"); @@ -597,7 +599,7 @@ void neuronspi_uart_start_tx(struct uart_port *port) } else { n_port->tx_work_count++; } - spin_unlock(&n_port->tx_lock); + spin_unlock_irqrestore(&n_port->tx_lock, flags); kthread_queue_work(&n_port->parent->kworker, &n_port->tx_work); } diff --git a/version.txt b/version.txt index f383842..a617845 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -Repository:neuron-kernel ActiveBranch:[uart_timeout] PrecedingRelease:v.0.12 PrecedingRevision:64(a816c68) LatestCommit:Wed Jun 27 14:59:12 CEST 2018 +Repository:neuron-kernel ActiveBranch:[uart_timeout] PrecedingRelease:v.0.12 PrecedingRevision:65(9168070) LatestCommit:Wed Jun 27 15:24:18 CEST 2018 -- 2.34.1