From 989fac909141e3c1c95dcead1f6041f504342270 Mon Sep 17 00:00:00 2001 From: Miroslav Ondra Date: Thu, 6 Sep 2018 10:05:47 +0200 Subject: [PATCH] cleaned neuronspi_devtype fixed unregistering --- modules/unipi/src/unipi_common.h | 22 ++----- modules/unipi/src/unipi_platform.c | 4 +- modules/unipi/src/unipi_spi.c | 100 ++++++++++++++++------------- modules/unipi/src/unipi_tty.c | 5 ++ modules/unipi/src/unipi_tty.h | 1 + modules/unipi/src/unipi_uart.c | 18 ++++-- 6 files changed, 79 insertions(+), 71 deletions(-) diff --git a/modules/unipi/src/unipi_common.h b/modules/unipi/src/unipi_common.h index d478b78..a97a013 100644 --- a/modules/unipi/src/unipi_common.h +++ b/modules/unipi/src/unipi_common.h @@ -69,7 +69,7 @@ #define NEURONSPI_MAX_BAUD 115200 #define NEURONSPI_FIFO_SIZE 256 #define NEURONSPI_FIFO_MIN_CONTINUOUS 50 -#define NEURONSPI_DETAILED_DEBUG 0 +#define NEURONSPI_DETAILED_DEBUG 1 #define NEURONSPI_LAST_TRANSFER_DELAY 40 #define MAX_RX_QUEUE_LEN 16 @@ -109,13 +109,14 @@ enum neuron_num_attribute_type { NEURON_NATTR_CURRENT_VALUE }; -struct neuronspi_devtype +/* + * struct neuronspi_devtype { u8 name[10]; s32 nr_gpio; s32 nr_uart; }; - +*/ struct neuronspi_op_buffer { @@ -150,24 +151,13 @@ struct neuronspi_port struct neuronspi_uart_data { - const struct neuronspi_devtype *devtype; + //const struct neuronspi_devtype *devtype; struct kthread_worker kworker; struct task_struct *kworker_task; struct neuronspi_port *p; // array p[p_count] u8 p_count; }; -// Instantiated once -struct neuronspi_char_driver -{ - s32 major_number; - u8 *message; - u16 message_size; - u32 open_counter; - struct class* driver_class; - struct device* dev; -}; - // Instantiated once per SPI device struct neuronspi_driver_data { @@ -177,11 +167,11 @@ struct neuronspi_driver_data //struct neuronspi_char_driver *char_driver; //struct uart_driver *serial_driver; -- this is global variable neuronspi_uart_driver_global //struct neuronspi_uart_data *uart_data; -- this global var neuronspi_uar_data_global + struct platform_device *board_device; struct neuronspi_led_driver *led_driver; struct neuronspi_gpio_driver *di_driver; struct neuronspi_gpio_driver *do_driver; struct neuronspi_gpio_driver *ro_driver; - struct platform_device *board_device; struct iio_dev *stm_ai_driver; struct iio_dev *stm_ao_driver; struct iio_dev **sec_ai_driver; diff --git a/modules/unipi/src/unipi_platform.c b/modules/unipi/src/unipi_platform.c index 2bb2643..906adf2 100644 --- a/modules/unipi/src/unipi_platform.c +++ b/modules/unipi/src/unipi_platform.c @@ -1799,7 +1799,7 @@ int neuronspi_regmap_hw_gather_write(void *context, const void *reg, size_t reg_ //u16 *mb_val_buf = (u16*)val; struct spi_device *spi = context; - printk(KERN_INFO "UNIPISPI: Regmap_hw_gather_write reg[%d](%d) val(%d):%8ph\n", *mb_reg_buf, reg_size, val_size, val); + printk(KERN_INFO "UNIPISPI: Regmap_hw_gather_write reg[%d](%zu) val(%zu):%8ph\n", *mb_reg_buf, reg_size, val_size, val); if (reg_size == sizeof(u16)) { return unipispi_modbus_write_register(spi, mb_reg_buf[0], *((u16*)val)); @@ -1931,7 +1931,7 @@ int neuronspi_regmap_hw_read(void *context, const void *reg_buf, size_t reg_size if (context == NULL) { return 0; } - printk(KERN_INFO "UNIPISPI: Regmap_hw_read reg[%d](%dB) val(%dB):%8ph\n", *mb_reg_buf, reg_size, val_size, val_buf); + printk(KERN_INFO "UNIPISPI: Regmap_hw_read reg[%d](%zuB) val(%zuB):%8ph\n", *mb_reg_buf, reg_size, val_size, val_buf); if (val_size == sizeof(u16)) { return unipispi_modbus_read_register(spi, *mb_reg_buf, (u16*) val_buf); diff --git a/modules/unipi/src/unipi_spi.c b/modules/unipi/src/unipi_spi.c index 50b70b5..8d5c3df 100644 --- a/modules/unipi/src/unipi_spi.c +++ b/modules/unipi/src/unipi_spi.c @@ -47,6 +47,16 @@ * Data Definitions * ********************/ +// Instantiated once +struct neuronspi_char_driver +{ + int major_number; + u32 open_counter; + struct class* driver_class; + struct device* dev; +}; + + struct mutex neuronspi_master_mutex; struct mutex unipi_inv_speed_mutex; int neuronspi_model_id = -1; @@ -59,6 +69,7 @@ static struct sched_param neuronspi_sched_param = { .sched_priority = MAX_RT_PRI struct neuronspi_char_driver neuronspi_cdrv = { + .major_number = -1, .dev = NULL }; @@ -283,14 +294,13 @@ int _neuronspi_spi_send_op(struct spi_device* spi_dev, s32 trans_count, const st int neuronspi_open (struct inode *inode_p, struct file *file_p) { struct neuronspi_file_data *f_internal_data; - if (neuronspi_s_dev == NULL || file_p == NULL || inode_p == NULL) { + if (file_p == NULL || inode_p == NULL) { return -1; } neuronspi_cdrv.open_counter += 1; f_internal_data = kzalloc(sizeof(*f_internal_data), GFP_ATOMIC); f_internal_data->recv_buf.second_message = kzalloc(NEURONSPI_BUFFER_MAX, GFP_ATOMIC); f_internal_data->send_buf.second_message = kzalloc(NEURONSPI_BUFFER_MAX, GFP_ATOMIC); - //f_internal_data->spi_device = neuronspi_s_dev; mutex_init(&f_internal_data->lock); file_p->private_data = f_internal_data; return 0; @@ -303,11 +313,8 @@ int neuronspi_release (struct inode *inode_p, struct file *file_p) return -1; } f_internal_data = (struct neuronspi_file_data*)file_p->private_data; - //f_internal_data->spi_device = NULL; kfree(f_internal_data->recv_buf.second_message); - f_internal_data->recv_buf.second_message = NULL; kfree(f_internal_data->send_buf.second_message); - f_internal_data->send_buf.second_message = NULL; kfree(f_internal_data); file_p->private_data = NULL; neuronspi_cdrv.open_counter -= 1; @@ -352,7 +359,7 @@ ssize_t neuronspi_read (struct file *file_p, char *buffer, size_t len, loff_t *o mutex_unlock(&(private_data->lock)); return -10; } - unipi_spi_trace(KERN_INFO "UNIPISPI: CDEV Read %d, nspi:%d msglen=%d offset=%d\n", len, + unipi_spi_trace(KERN_INFO "UNIPISPI: CDEV Read %zu, nspi:%d msglen=%d offset=%d\n", len, (private_data->device_index), private_data->message_len, (int)*offset); if (private_data->has_first_message & UNIPISPI_OP_MODE_SEND_HEADER) { @@ -396,7 +403,7 @@ ssize_t neuronspi_write (struct file *file_p, const char *buffer, size_t len, lo neuronspi_cdrv.open_counter = 1; } - unipi_spi_trace(KERN_INFO "UNIPISPI: CDEV Write len:%d\n", len); + unipi_spi_trace(KERN_INFO "UNIPISPI: CDEV Write len:%zu\n", len); if ((buffer == NULL) || (len == 0)) { return 0; // Void write } @@ -832,7 +839,7 @@ const char name_unknown[] = "UNKNOWN\0"; s32 neuronspi_spi_probe(struct spi_device *spi) { - const struct neuronspi_devtype *devtype; + //const struct neuronspi_devtype *devtype; struct neuronspi_driver_data *n_spi; struct neuronspi_op_buffer recv_op; u8 first_probe[UNIPISPI_PROBE_MESSAGE_LEN]; @@ -883,12 +890,12 @@ s32 neuronspi_spi_probe(struct spi_device *spi) of_property_read_u32_array(spi->dev.of_node, "neuron-board-index", &(n_spi->neuron_index), 1); of_property_read_u32_array(spi->dev.of_node, "neuron-probe-always-succeeds", &(probe_always_succeeds), 1); of_property_read_u32_array(spi->dev.of_node, "neuron-always-create-tty", &(always_create_uart), 1); - devtype = (struct neuronspi_devtype *)of_id->data; + //devtype = (struct neuronspi_devtype *)of_id->data; unipi_spi_trace(KERN_INFO "UNIPISPI: CS%d, Device Tree Node defined index=%d\n", spi->chip_select, n_spi->neuron_index); } else { - const struct spi_device_id *id_entry = spi_get_device_id(spi); - devtype = (struct neuronspi_devtype *)id_entry->driver_data; + //const struct spi_device_id *id_entry = spi_get_device_id(spi); + //devtype = (struct neuronspi_devtype *)id_entry->driver_data; } @@ -920,7 +927,7 @@ s32 neuronspi_spi_probe(struct spi_device *spi) break; } } - n_spi->ideal_frequency = (neuronspi_is_noirq_model(lower_board) ? NEURONSPI_SLOWER_FREQ : NEURONSPI_COMMON_FREQ; + n_spi->ideal_frequency = neuronspi_is_noirq_model(lower_board) ? NEURONSPI_SLOWER_FREQ : NEURONSPI_COMMON_FREQ; no_irq = neuronspi_is_noirq_model(lower_board); printk(KERN_INFO "UNIPISPI: Detected UniPi Board %s (L:%x U:%x C:%x) at CS%d (nspi%d)\n\t\t\tFw: v%d.%d Uarts:%d, reg1001-4: %04x %04x %04x %04x\n", @@ -1033,12 +1040,14 @@ s32 neuronspi_spi_probe(struct spi_device *spi) neuronspi_spi_set_irqs(spi, 0x5); kthread_init_work(&(n_spi->irq_work), neuronspi_irq_proc); // prepare work function for interrupt status checking - //n_spi->poll_thread = NULL; if (!no_irq) { n_spi->no_irq = 0; ret = devm_request_irq(&(spi->dev), spi->irq, neuronspi_spi_irq, 0x81, dev_name(&(spi->dev)), spi); unipi_spi_trace(KERN_DEBUG "UNIPISPI: SPI IRQ %d registration: ret=%d\n", spi->irq, ret); - } else { + no_irq = (ret !=0); + ret = 0; + } + if (no_irq) { n_spi->no_irq = 1; hrtimer_init(&n_spi->poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); n_spi->poll_timer.function = neuronspi_poll_timer_func; @@ -1056,6 +1065,8 @@ s32 neuronspi_spi_remove(struct spi_device *spi) if (n_spi->no_irq) { hrtimer_cancel(&n_spi->poll_timer); + } else { + devm_free_irq(&(spi->dev), spi->irq, spi); } kthread_flush_worker(&n_spi->primary_worker); @@ -1066,19 +1077,15 @@ s32 neuronspi_spi_remove(struct spi_device *spi) kfree(n_spi->led_driver); n_spi->led_driver = NULL; } - printk(KERN_INFO "UNIPISPI: LED DRIVER UNREGISTERED\n"); + printk(KERN_INFO "UNIPISPI: LED Driver unregistered\n"); if (n_spi->di_driver) { neuronspi_gpio_remove(n_spi->di_driver); } if (n_spi->do_driver) { neuronspi_gpio_remove(n_spi->do_driver); } if (n_spi->ro_driver) { neuronspi_gpio_remove(n_spi->ro_driver); } - printk(KERN_INFO "UNIPISPI: GPIO DRIVER UNREGISTERED\n"); + printk(KERN_INFO "UNIPISPI: GPIO Driver unregistered\n"); - if (n_spi->stm_ai_driver) { - iio_device_unregister(n_spi->stm_ai_driver); - } - if (n_spi->stm_ao_driver) { - iio_device_unregister(n_spi->stm_ao_driver); - } + if (n_spi->stm_ai_driver) { iio_device_unregister(n_spi->stm_ai_driver); } + if (n_spi->stm_ao_driver) { iio_device_unregister(n_spi->stm_ao_driver); } if (n_spi->sec_ai_driver) { for (i = 0; i < n_spi->features->sec_ai_count; i++) { iio_device_unregister(n_spi->sec_ai_driver[i]); @@ -1093,8 +1100,8 @@ s32 neuronspi_spi_remove(struct spi_device *spi) kfree(n_spi->sec_ao_driver); n_spi->sec_ao_driver = NULL; } - printk(KERN_INFO "UNIPISPI: IIO DRIVER UNREGISTERED\n"); - printk(KERN_INFO "UNIPISPI: SPI/UART DRIVER UNREGISTERED\n"); + printk(KERN_INFO "UNIPISPI: IIO Driver unregistered\n"); + printk(KERN_INFO "UNIPISPI: SPI/UART Driver unregistered\n"); if (n_spi->board_device) { platform_set_drvdata(n_spi->board_device, 0); platform_device_unregister(n_spi->board_device); @@ -1115,50 +1122,55 @@ struct file_operations file_ops = }; -s32 char_register_driver(void) +int char_register_driver(void) { - s32 ret = 0; + int major; + + if (neuronspi_cdrv.major_number >= 0) return 0; // Character device registration unipi_spi_trace(KERN_DEBUG "UNIPISPI: CDEV Initialising Character Device\n"); - neuronspi_cdrv.major_number = register_chrdev(0, NEURON_DEVICE_NAME, &file_ops); - if (neuronspi_cdrv.major_number < 0){ + major = register_chrdev(0, NEURON_DEVICE_NAME, &file_ops); + if (major < 0){ printk(KERN_ALERT "NEURONSPI: CDEV Failed to register chrdev\n"); - return neuronspi_cdrv.major_number; + return major; } - unipi_spi_trace_1(KERN_DEBUG "UNIPISPI: CDEV major number %d\n", neuronspi_cdrv.major_number); + unipi_spi_trace_1(KERN_DEBUG "UNIPISPI: CDEV major number %d\n", major); // Character class registration neuronspi_cdrv.driver_class = class_create(THIS_MODULE, NEURON_DEVICE_CLASS); if (IS_ERR(neuronspi_cdrv.driver_class)) { - unregister_chrdev(neuronspi_cdrv.major_number, NEURON_DEVICE_NAME); + unregister_chrdev(major, NEURON_DEVICE_NAME); printk(KERN_ALERT "NEURONSPI: CDEV Failed to register device class\n"); return PTR_ERR(neuronspi_cdrv.driver_class); } unipi_spi_trace_1(KERN_DEBUG "UNIPISPI: CDEV Device class registered\n"); // Device driver registration - neuronspi_cdrv.dev = device_create_with_groups(neuronspi_cdrv.driver_class, &(neuron_plc_dev->dev), MKDEV(neuronspi_cdrv.major_number, 0), NULL, neuron_plc_attr_groups, NEURON_DEVICE_NAME); + neuronspi_cdrv.dev = device_create_with_groups(neuronspi_cdrv.driver_class, &(neuron_plc_dev->dev), \ + MKDEV(major, 0), NULL, neuron_plc_attr_groups, NEURON_DEVICE_NAME); if (IS_ERR(neuronspi_cdrv.dev)) { class_destroy(neuronspi_cdrv.driver_class); - unregister_chrdev(neuronspi_cdrv.major_number, NEURON_DEVICE_NAME); + unregister_chrdev(major, NEURON_DEVICE_NAME); printk(KERN_ALERT "NEURONSPI: CDEV Failed to create the device\n"); return PTR_ERR(neuronspi_cdrv.dev); } - unipi_spi_trace(KERN_DEBUG "UNIPISPI: CDEV Device created. Major number %d\n", neuronspi_cdrv.major_number); + printk(KERN_DEBUG "UNIPISPI: Device /dev/%s (%d:0) created.\n", NEURON_DEVICE_NAME, major); - return ret; + neuronspi_cdrv.major_number = major; + return 0; } -s32 char_unregister_driver(void) +void char_unregister_driver(void) { + if (neuronspi_cdrv.major_number < 0) return; + device_destroy(neuronspi_cdrv.driver_class, MKDEV(neuronspi_cdrv.major_number, 0)); // Destroy the device - class_unregister(neuronspi_cdrv.driver_class); // Unregister the class + //class_unregister(neuronspi_cdrv.driver_class); // registrace nebyla volana class_destroy(neuronspi_cdrv.driver_class); // Destroy the class - unregister_chrdev(neuronspi_cdrv.major_number, NEURON_DEVICE_NAME); // Unregister the major number - printk(KERN_INFO "UNIPISPI: CDEV unloaded\n"); - return 0; + unregister_chrdev(neuronspi_cdrv.major_number, NEURON_DEVICE_NAME); // Unregister the major number + unipi_spi_trace(KERN_INFO "UNIPISPI: CDEV unloaded\n"); } /********************* @@ -1204,12 +1216,7 @@ static s32 __init neuronspi_init(void) wake_up_process(neuronspi_invalidate_thread); } - if (!(neuronspi_cdrv.major_number)) { // Register character device if it doesn't exist - ret = char_register_driver(); - if (ret) { - printk(KERN_ERR "UNIPISPI: Failed to register the neuronspi character driver, ERR:%d\n", ret); - } - } + char_register_driver(); neuronspi_uart_driver_init(); neuronspi_uart_probe_all(); @@ -1229,6 +1236,7 @@ static void __exit neuronspi_exit(void) } char_unregister_driver(); neuronspi_uart_driver_exit(); + unipi_tty_exit(); spi_unregister_driver(&neuronspi_spi_driver); if (neuron_plc_dev) { platform_device_unregister(neuron_plc_dev); diff --git a/modules/unipi/src/unipi_tty.c b/modules/unipi/src/unipi_tty.c index 1e21a11..c8e0acc 100644 --- a/modules/unipi/src/unipi_tty.c +++ b/modules/unipi/src/unipi_tty.c @@ -985,3 +985,8 @@ int __init unipi_tty_init(void) } return 0; } + +void __exit unipi_tty_exit(void) +{ + tty_unregister_ldisc(N_PROFIBUS_FDL); +} \ No newline at end of file diff --git a/modules/unipi/src/unipi_tty.h b/modules/unipi/src/unipi_tty.h index 371f133..b4a6cc3 100644 --- a/modules/unipi/src/unipi_tty.h +++ b/modules/unipi/src/unipi_tty.h @@ -18,5 +18,6 @@ #include "unipi_common.h" int unipi_tty_init(void); +void unipi_tty_exit(void); #endif /* MODULES_UNIPI_SRC_UNIPI_TTY_H_ */ diff --git a/modules/unipi/src/unipi_uart.c b/modules/unipi/src/unipi_uart.c index 7019943..0445503 100644 --- a/modules/unipi/src/unipi_uart.c +++ b/modules/unipi/src/unipi_uart.c @@ -559,7 +559,7 @@ void neuronspi_uart_shutdown(struct uart_port *port) } -s32 neuronspi_uart_remove(struct neuronspi_uart_data *u_data) +s32 neuronspi_uart_remove(void) { struct neuronspi_driver_data *d_data; struct spi_device *spi; @@ -570,18 +570,20 @@ s32 neuronspi_uart_remove(struct neuronspi_uart_data *u_data) if (!(neuronspi_s_dev[i] == NULL)) { spi = neuronspi_s_dev[i]; d_data = spi_get_drvdata(spi); + d_data->uart_count = 0; } } - for (i = 0; i < u_data->p_count; i++) { - port = u_data->p + i; + if (neuronspi_uart_data_global->kworker_task) { + kthread_destroy_worker(&neuronspi_uart_data_global->kworker); + } + for (i = 0; i < neuronspi_uart_data_global->p_count; i++) { + port = neuronspi_uart_data_global->p + i; hrtimer_cancel(&port->tx_timer); uart_remove_one_port(neuronspi_uart_driver_global, &port->port); neuronspi_uart_power(&port->port, 0); kfree(port->rx_queue_primary); kfree(port->rx_queue_secondary); } - - kthread_flush_worker(&u_data->kworker); return 0; } @@ -651,7 +653,7 @@ int neuronspi_uart_probe(struct spi_device* spi, struct neuronspi_driver_data *n kthread_init_work(&(port->tx_work), neuronspi_uart_tx_proc); kthread_init_work(&(port->rx_work), neuronspi_uart_rx_proc); uart_add_one_port(neuronspi_uart_driver_global, &port->port); - printk(KERN_INFO "UNIPIUART: Add port ttyNS%d on UniPi Board nspi%d port:%d\n", neuronspi_uart_data_global->p_count, port->dev_index, port->dev_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)); n_spi->uart_count++; @@ -741,8 +743,10 @@ int neuronspi_uart_driver_init(void) int neuronspi_uart_driver_exit(void) { if (neuronspi_uart_driver_global) { - neuronspi_uart_remove(neuronspi_uart_data_global); + neuronspi_uart_remove(); uart_unregister_driver(neuronspi_uart_driver_global); + if (neuronspi_uart_data_global->p) + kfree(neuronspi_uart_data_global->p); kfree(neuronspi_uart_driver_global); kfree(neuronspi_uart_data_global); } -- 2.34.1