From: Miroslav Ondra Date: Thu, 6 Sep 2018 17:50:08 +0000 (+0200) Subject: fixed primary_worker allocation X-Git-Url: http://git.graph-it.com/?a=commitdiff_plain;h=4c72b9ba8fe32351b2f64ab918651d79e2db31f5;p=graphit%2Funipi-kernel.git fixed primary_worker allocation fixed uart ports removing temporary disabled LED, GPIO, IIO subsystem --- diff --git a/modules/unipi/src/unipi_common.h b/modules/unipi/src/unipi_common.h index a97a013..bf9698e 100644 --- a/modules/unipi/src/unipi_common.h +++ b/modules/unipi/src/unipi_common.h @@ -129,6 +129,7 @@ struct neuronspi_port struct uart_port port; u8 dev_index; // index into global array neuronspi_s_dev u8 dev_port; // index of port on neuronspi device + struct neuronspi_driver_data *n_spi; // shorthand to n_spi spinlock_t rx_queue_lock; u8* rx_queue_primary; @@ -151,9 +152,6 @@ struct neuronspi_port struct neuronspi_uart_data { - //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; }; @@ -177,8 +175,7 @@ struct neuronspi_driver_data struct iio_dev **sec_ai_driver; struct iio_dev **sec_ao_driver; - struct kthread_worker primary_worker; - struct task_struct *primary_worker_task; + struct kthread_worker *primary_worker; struct kthread_work irq_work; struct hrtimer poll_timer; int poll_enabled; diff --git a/modules/unipi/src/unipi_misc.c b/modules/unipi/src/unipi_misc.c index 1d6a75f..9ab94b8 100644 --- a/modules/unipi/src/unipi_misc.c +++ b/modules/unipi/src/unipi_misc.c @@ -53,7 +53,7 @@ void neuronspi_led_set_brightness(struct led_classdev *ldev, enum led_brightness unsigned long flags; spin_lock_irqsave(&led->lock, flags); led->brightness = brightness; - kthread_queue_work(&n_spi->primary_worker, &led->led_work); + kthread_queue_work(n_spi->primary_worker, &led->led_work); spin_unlock_irqrestore(&led->lock, flags); } diff --git a/modules/unipi/src/unipi_platform.c b/modules/unipi/src/unipi_platform.c index 906adf2..3b34ded 100644 --- a/modules/unipi/src/unipi_platform.c +++ b/modules/unipi/src/unipi_platform.c @@ -1647,7 +1647,7 @@ s32 neuronspi_regmap_invalidate(void *data) for (i = 0; i < NEURONSPI_MAX_DEVS; i++) { if (neuronspi_s_dev[i] != NULL) { struct neuronspi_driver_data *d_data = spi_get_drvdata(neuronspi_s_dev[i]); - if (d_data->combination_id == 0xFF) { + if ((d_data->combination_id == 0xFF) || (d_data->reg_map == NULL)) { continue; } neuronspi_regmap_invalidate_device(d_data->reg_map, NEURONSPI_BOARDTABLE[d_data->combination_id].definition, freq_cnt); diff --git a/modules/unipi/src/unipi_spi.c b/modules/unipi/src/unipi_spi.c index 8d5c3df..833bdac 100644 --- a/modules/unipi/src/unipi_spi.c +++ b/modules/unipi/src/unipi_spi.c @@ -246,7 +246,8 @@ int _neuronspi_spi_send_op(struct spi_device* spi_dev, s32 trans_count, const st // read queue length port->rx_remain = recv_buf->first_message[2]; unipi_spi_trace(KERN_INFO "UNIPISPI: UART Buffer:%d, ttyNS%d(%d:%d)\n", port->rx_remain, port->port.line, port->dev_index, port->dev_port); - kthread_queue_work(&neuronspi_uart_data_global->kworker, &port->rx_work); + //kthread_queue_work(&neuronspi_uart_data_global->kworker, &port->rx_work); + kthread_queue_work(d_data->primary_worker, &port->rx_work); } } } @@ -779,30 +780,10 @@ static enum hrtimer_restart neuronspi_poll_timer_func(struct hrtimer *timer) struct neuronspi_driver_data* n_spi = ((container_of((timer), struct neuronspi_driver_data, poll_timer))); unipi_spi_trace_1(KERN_INFO "UNIPISPI: nspi%d POLL IRQ\n", n_spi->neuron_index); - kthread_queue_work(&n_spi->primary_worker, &n_spi->irq_work); + kthread_queue_work(n_spi->primary_worker, &n_spi->irq_work); return HRTIMER_NORESTART; } -/* -s32 neuronspi_uart_poll(void *data) -{ - struct neuronspi_driver_data *d_data = (struct neuronspi_driver_data*) data; - //struct neuronspi_uart_data *u_data; - s32 i; - while (!kthread_should_stop()) { - usleep_range(2000,8000); - if (d_data->uart_count) { - //u_data = d_data->uart_data; - for (i = 0; i < neuronspi_uart_data_global->p_count; i++) { - if (neuronspi_uart_data_global->p[i].dev_index == d_data->neuron_index) { - kthread_queue_work(&neuronspi_uart_data_global->kworker, &neuronspi_uart_data_global->p[i].irq_work); - } - } - } - } - return 0; -} -*/ irqreturn_t neuronspi_spi_irq(s32 irq, void *dev_id) { @@ -811,7 +792,7 @@ irqreturn_t neuronspi_spi_irq(s32 irq, void *dev_id) struct neuronspi_driver_data *n_spi = spi_get_drvdata(spi); unipi_spi_trace(KERN_INFO "UNIPISPI: nspi%d SPI IRQ\n", n_spi->neuron_index); - kthread_queue_work(&n_spi->primary_worker, &n_spi->irq_work); + kthread_queue_work(n_spi->primary_worker, &n_spi->irq_work); return IRQ_HANDLED; } @@ -826,7 +807,7 @@ void neuronspi_enable_uart_interrupt(struct neuronspi_port* n_port) // start polling n_spi->poll_enabled = 1; // invoke first probe -> which invokes hrtimer - kthread_queue_work(&n_spi->primary_worker, &n_spi->irq_work); + kthread_queue_work(n_spi->primary_worker, &n_spi->irq_work); } } @@ -850,6 +831,7 @@ s32 neuronspi_spi_probe(struct spi_device *spi) const char *board_name = name_unknown; u32 probe_always_succeeds; u32 always_create_uart; + struct kthread_worker *worker; unsigned long flags; @@ -927,10 +909,10 @@ 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_slower_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", + printk(KERN_INFO "UNIPISPI: UniPi Board %s (L:%x U:%x C:%x) at CS%d (nspi%d) detected.\n\t\t\tFw: v%d.%d Uarts:%d, reg1001-4: %04x %04x %04x %04x\n", board_name, hi(lower_board), upper_board, hardware_model, spi->chip_select, n_spi->neuron_index, hi(n_spi->firmware_version), lo(n_spi->firmware_version), uart_count, REG1000(first_probe,1001), REG1000(first_probe,1002), REG1000(first_probe,1003), REG1000(first_probe,1004)); @@ -940,7 +922,7 @@ s32 neuronspi_spi_probe(struct spi_device *spi) if (always_create_uart) uart_count = 1; n_spi->ideal_frequency = NEURONSPI_SLOWER_FREQ; no_irq = 1; - printk(KERN_INFO "UNIPISPI: Probe assigned DUMMY UniPi Board at CS%d (nspi%d) Uarts:%d, uses freq. %d Hz\n", + printk(KERN_INFO "UNIPISPI: DUMMY UniPi Board at CS%d (nspi%d) assigned. Uarts:%d, uses freq. %d Hz\n", spi->chip_select, n_spi->neuron_index, uart_count, n_spi->ideal_frequency); } else { @@ -950,17 +932,16 @@ s32 neuronspi_spi_probe(struct spi_device *spi) return ret; } - // Prepare worker for interrupt, LEDs, - kthread_init_worker(&n_spi->primary_worker); - - n_spi->primary_worker_task = kthread_run(kthread_worker_fn, &n_spi->primary_worker, "unipispi%d", n_spi->neuron_index); - if (IS_ERR(n_spi->primary_worker_task )) { - ret = PTR_ERR(n_spi->primary_worker_task); + // Prepare worker for interrupt, LEDs, UARTs + worker = kthread_create_worker(0, "unipispi%d", n_spi->neuron_index); + if (IS_ERR(worker)) { kfree(n_spi); - return ret; - } - sched_setscheduler(n_spi->primary_worker_task, SCHED_FIFO, &neuronspi_sched_param); - + return PTR_ERR(worker); + } + sched_setscheduler(worker->task, SCHED_FIFO, &neuronspi_sched_param); + n_spi->primary_worker = worker; + +/* n_spi->reg_map = regmap_init(&(spi->dev), &neuronspi_regmap_bus, spi, &neuronspi_regmap_config_default); spin_lock_init(&n_spi->sysfs_regmap_lock); if (n_spi->features) { @@ -969,17 +950,17 @@ s32 neuronspi_spi_probe(struct spi_device *spi) } else { n_spi->regstart_table = NULL; } - - //n_spi->char_driver = &neuronspi_cdrv; +*/ + // save device into global array spin_lock_irqsave(neuronspi_probe_spinlock, flags); - - neuronspi_s_dev[n_spi->neuron_index] = spi; spi_set_drvdata(spi, n_spi); + neuronspi_s_dev[n_spi->neuron_index] = spi; if (neuronspi_probe_count == NEURONSPI_MAX_DEVS) { neuronspi_model_id = neuronspi_find_model_id(neuronspi_probe_count); } spin_unlock_irqrestore(neuronspi_probe_spinlock, flags); + if (neuronspi_model_id != -1) { printk(KERN_INFO "UNIPISPI: Detected UniPi board combination corresponding to %s\n", NEURONSPI_MODELTABLE[neuronspi_model_id].model_name); } @@ -991,7 +972,7 @@ s32 neuronspi_spi_probe(struct spi_device *spi) neuron_plc_dev->dev.groups = neuron_plc_attr_groups; platform_device_add(neuron_plc_dev); } - +/* n_spi->board_device = neuronspi_board_device_probe(n_spi); if (n_spi->features) { @@ -1024,7 +1005,7 @@ s32 neuronspi_spi_probe(struct spi_device *spi) n_spi->sec_ao_driver = neuronspi_sec_ao_probe(n_spi->features->sec_ao_count, n_spi->neuron_index, n_spi->board_device); } } - +*/ n_spi->uart_count_to_probe = uart_count; if (uart_count) { if (neuronspi_uart_driver_global != NULL) { @@ -1060,29 +1041,31 @@ s32 neuronspi_spi_probe(struct spi_device *spi) s32 neuronspi_spi_remove(struct spi_device *spi) { int i; + int neuron_index; struct neuronspi_driver_data *n_spi = spi_get_drvdata(spi); if (n_spi) { - + neuron_index = n_spi->neuron_index; 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); - + neuronspi_uart_remove(spi); +/* if (n_spi->led_driver) { for (i = 0; i < n_spi->features->led_count; i++) { led_classdev_unregister(&(n_spi->led_driver[i].ldev)); + kthread_flush_work(&(n_spi->led_driver[i].led_work)); } kfree(n_spi->led_driver); n_spi->led_driver = NULL; + unipi_spi_trace(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"); + unipi_spi_trace(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); } @@ -1100,13 +1083,19 @@ 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"); + unipi_spi_trace(KERN_INFO "UNIPISPI: IIO Driver unregistered\n"); +*/ if (n_spi->board_device) { platform_set_drvdata(n_spi->board_device, 0); platform_device_unregister(n_spi->board_device); } + /*if (n_spi->reg_map) + regmap_exit(n_spi->reg_map); */ + + kthread_destroy_worker(n_spi->primary_worker); + neuronspi_s_dev[neuron_index] = NULL; kfree(n_spi); + printk(KERN_INFO "UNIPISPI: UniPi Board nspi%d removed\n", neuron_index); } return 0; } @@ -1156,7 +1145,7 @@ int char_register_driver(void) printk(KERN_ALERT "NEURONSPI: CDEV Failed to create the device\n"); return PTR_ERR(neuronspi_cdrv.dev); } - printk(KERN_DEBUG "UNIPISPI: Device /dev/%s (%d:0) created.\n", NEURON_DEVICE_NAME, major); + printk(KERN_DEBUG "UNIPISPI: ModBus/SPI interface /dev/%s (%d:0) created.\n", NEURON_DEVICE_NAME, major); neuronspi_cdrv.major_number = major; return 0; @@ -1211,10 +1200,10 @@ static s32 __init neuronspi_init(void) } printk(KERN_INFO "UNIPISPI: SPI Driver Registered, Major Version: %s\n", NEURONSPI_MAJOR_VERSIONSTRING); - neuronspi_invalidate_thread = kthread_create(neuronspi_regmap_invalidate, NULL, "unipispi_inv"); - if (neuronspi_invalidate_thread != NULL) { - wake_up_process(neuronspi_invalidate_thread); - } + neuronspi_invalidate_thread = kthread_run(neuronspi_regmap_invalidate, NULL, "unipispi_inv"); + if (IS_ERR(neuronspi_invalidate_thread)) { + neuronspi_invalidate_thread = NULL; + } char_register_driver(); @@ -1231,8 +1220,9 @@ static void __exit neuronspi_exit(void) { unipi_spi_trace(KERN_INFO "UNIPISPI: Open Counter is %d\n", neuronspi_cdrv.open_counter); - if (neuronspi_invalidate_thread) { + if (neuronspi_invalidate_thread) { kthread_stop(neuronspi_invalidate_thread); + neuronspi_invalidate_thread = NULL; } char_unregister_driver(); neuronspi_uart_driver_exit(); diff --git a/modules/unipi/src/unipi_uart.c b/modules/unipi/src/unipi_uart.c index 0445503..f11f337 100644 --- a/modules/unipi/src/unipi_uart.c +++ b/modules/unipi/src/unipi_uart.c @@ -45,7 +45,7 @@ struct neuronspi_uart_data* neuronspi_uart_data_global = NULL; struct uart_driver* neuronspi_uart_driver_global = NULL; //unsigned long neuronspi_lines; -static struct sched_param neuronspi_sched_param = { .sched_priority = MAX_RT_PRIO / 2 }; +//static struct sched_param neuronspi_sched_param = { .sched_priority = MAX_RT_PRIO / 2 }; void neuronspi_uart_update_timeout(struct neuronspi_port *n_port, unsigned int cflag, unsigned int baud); @@ -281,7 +281,8 @@ void neuronspi_uart_start_tx(struct uart_port *port) struct neuronspi_port *n_port = to_neuronspi_port(port,port); unipi_uart_trace("Start TX\n"); - if (!kthread_queue_work(&neuronspi_uart_data_global->kworker, &n_port->tx_work)) { + if (!kthread_queue_work(n_port->n_spi->primary_worker, &n_port->tx_work)) { + //if (!kthread_queue_work(&neuronspi_uart_data_global->kworker, &n_port->tx_work)) { //unipi_uart_trace("TX WORK OVERFLOW\n"); } } @@ -393,7 +394,8 @@ void neuronspi_uart_handle_tx(struct neuronspi_port *port) port->port.icount.tx++; spin_unlock_irqrestore(&port->port.lock, flags); port->port.x_char = 0; - kthread_queue_work(&neuronspi_uart_data_global->kworker, &port->tx_work); + kthread_queue_work(port->n_spi->primary_worker, &port->tx_work); + //kthread_queue_work(&neuronspi_uart_data_global->kworker, &port->tx_work); return; } @@ -459,7 +461,8 @@ void neuronspi_uart_handle_tx(struct neuronspi_port *port) spin_unlock_irqrestore(&port->port.lock, flags); if (to_send) { // reschedule work - kthread_queue_work(&neuronspi_uart_data_global->kworker, &port->tx_work); + kthread_queue_work(port->n_spi->primary_worker, &port->tx_work); + //kthread_queue_work(&neuronspi_uart_data_global->kworker, &port->tx_work); } else { // set timer to check tx_empty unipi_uart_trace_1("ttyNS%d Handle TX. Start timer=%llu", port->port.line, to_send_packet * port->one_char_nsec); @@ -480,7 +483,8 @@ static enum hrtimer_restart neuronspi_uart_timer_func(struct hrtimer *timer) { struct neuronspi_port* n_port = ((container_of((timer), struct neuronspi_port, tx_timer))); - kthread_queue_work(&neuronspi_uart_data_global->kworker, &n_port->tx_work); + kthread_queue_work(n_port->n_spi->primary_worker, &n_port->tx_work); + //kthread_queue_work(&neuronspi_uart_data_global->kworker, &n_port->tx_work); return HRTIMER_NORESTART; } @@ -534,7 +538,8 @@ void neuronspi_uart_rx_proc(struct kthread_work *ws) } if (n_port->rx_remain > 0) { - kthread_queue_work(&neuronspi_uart_data_global->kworker, &n_port->rx_work); + kthread_queue_work(n_port->n_spi->primary_worker, &n_port->rx_work); + //kthread_queue_work(&neuronspi_uart_data_global->kworker, &n_port->rx_work); } kfree(recv_buf); } @@ -559,32 +564,27 @@ void neuronspi_uart_shutdown(struct uart_port *port) } -s32 neuronspi_uart_remove(void) +void neuronspi_uart_remove(struct spi_device* spi) { - struct neuronspi_driver_data *d_data; - struct spi_device *spi; + struct neuronspi_driver_data *n_spi = spi_get_drvdata(spi); struct neuronspi_port *port; - int i; + int i, uart_count; + + uart_count = n_spi->uart_count; + n_spi->uart_count = 0; - for (i = 0; i < NEURONSPI_MAX_DEVS; i++) { - if (!(neuronspi_s_dev[i] == NULL)) { - spi = neuronspi_s_dev[i]; - d_data = spi_get_drvdata(spi); - d_data->uart_count = 0; - } - } - 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; + for (i = 0; i < uart_count; i++) { + port = neuronspi_uart_data_global->p + i + n_spi->uart_pindex; hrtimer_cancel(&port->tx_timer); uart_remove_one_port(neuronspi_uart_driver_global, &port->port); + kthread_flush_work(&(port->rx_work)); + kthread_flush_work(&(port->tx_work)); + neuronspi_uart_power(&port->port, 0); kfree(port->rx_queue_primary); kfree(port->rx_queue_secondary); + printk(KERN_INFO "UNIPIUART: Serial port ttyNS%d removed\n", i + n_spi->uart_pindex); } - return 0; } @@ -625,7 +625,8 @@ int neuronspi_uart_probe(struct spi_device* spi, struct neuronspi_driver_data *n port->port.dev = &(spi->dev); port->dev_index = n_spi->neuron_index; - port->dev_port = i; //neuronspi_uart_data_global->p_count; + port->dev_port = i; + port->n_spi = n_spi; // shorthand to n_spi port->port.line = neuronspi_uart_data_global->p_count; port->port.irq = spi->irq; @@ -691,6 +692,7 @@ int neuronspi_uart_probe_all(void) unipi_uart_trace("Allocated port structure for %d ttyNS devices", NEURONSPI_MAX_UART); } + /* if (neuronspi_uart_data_global->kworker_task == NULL) { kthread_init_worker(&neuronspi_uart_data_global->kworker); @@ -703,7 +705,7 @@ int neuronspi_uart_probe_all(void) sched_setscheduler(neuronspi_uart_data_global->kworker_task, SCHED_FIFO, &neuronspi_sched_param); unipi_uart_trace("KWorker unipiuart started\n"); } - + */ ret = neuronspi_uart_probe(spi, n_spi); if (ret) break; // max number of uarts reached } @@ -742,8 +744,13 @@ int neuronspi_uart_driver_init(void) int neuronspi_uart_driver_exit(void) { + int i; if (neuronspi_uart_driver_global) { - neuronspi_uart_remove(); + for (i = 0; i < NEURONSPI_MAX_DEVS; i++) { + if (neuronspi_s_dev[i] != NULL) { + neuronspi_uart_remove(neuronspi_s_dev[i]); + } + } uart_unregister_driver(neuronspi_uart_driver_global); if (neuronspi_uart_data_global->p) kfree(neuronspi_uart_data_global->p); diff --git a/modules/unipi/src/unipi_uart.h b/modules/unipi/src/unipi_uart.h index b5c32a2..57a85a8 100644 --- a/modules/unipi/src/unipi_uart.h +++ b/modules/unipi/src/unipi_uart.h @@ -39,6 +39,7 @@ void neuronspi_rx_queue_swap(struct neuronspi_port *port); int neuronspi_uart_driver_init(void); int neuronspi_uart_driver_exit(void); int neuronspi_uart_probe(struct spi_device* spi, struct neuronspi_driver_data *n_spi); +void neuronspi_uart_remove(struct spi_device* spi); int neuronspi_uart_probe_all(void); /*********************