Skip to content

Commit

Permalink
sensors: add workqueue to EV3/UART line discipline
Browse files Browse the repository at this point in the history
Hopefully this will help throughput of the sensors by having each sensor
use its own kernel thread instead of sharing the main system workqueue.
  • Loading branch information
dlech committed Apr 10, 2016
1 parent 8129c6e commit fa0d807
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions sensors/ev3_uart_sensor_ld.c
@@ -1,7 +1,7 @@
/*
* LEGO MINDSTORMS EV3 UART Sensor tty line discipline
*
* Copyright (C) 2014 David Lechner <david@lechnology.com>
* Copyright (C) 2014,2016 David Lechner <david@lechnology.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -180,6 +180,7 @@ enum ev3_uart_info_flags {
* @tty: Pointer to the tty device that the sensor is connected to
* @in_port: The input port device associated with this tty.
* @sensor: The lego-sensor class structure for the sensor.
* @wq: Workqueue for exclusive use by this driver.
* @rx_data_work: Workqueue item for handling received data.
* @send_ack_work: Used to send ACK after a delay.
* @change_bitrate_work: Used to change the baud rate after a delay.
Expand Down Expand Up @@ -220,6 +221,7 @@ struct ev3_uart_port_data {
struct tty_struct *tty;
struct lego_port_device *in_port;
struct lego_sensor_device sensor;
struct workqueue_struct *wq;
struct work_struct rx_data_work;
struct delayed_work send_ack_work;
struct work_struct change_bitrate_work;
Expand Down Expand Up @@ -413,7 +415,7 @@ static void ev3_uart_send_ack(struct work_struct *work)
}

mdelay(4);
schedule_work(&port->change_bitrate_work);
queue_work(port->wq, &port->change_bitrate_work);
}

static void ev3_uart_change_bitrate(struct work_struct *work)
Expand Down Expand Up @@ -462,7 +464,7 @@ enum hrtimer_restart ev3_uart_keep_alive_timer_callback(struct hrtimer *timer)
if (port->num_data_err > EV3_UART_MAX_DATA_ERR) {
port->synced = 0;
port->new_baud_rate = EV3_UART_SPEED_MIN;
schedule_work(&port->change_bitrate_work);
queue_work(port->wq, &port->change_bitrate_work);
return HRTIMER_NORESTART;
}
}
Expand Down Expand Up @@ -630,8 +632,8 @@ static void ev3_uart_handle_rx_data(struct work_struct *work)
port->last_err = "Did not receive all required INFO.";
goto err_invalid_state;
}
schedule_delayed_work(&port->send_ack_work,
msecs_to_jiffies(EV3_UART_SEND_ACK_DELAY));
queue_delayed_work(port->wq, &port->send_ack_work,
msecs_to_jiffies(EV3_UART_SEND_ACK_DELAY));
port->info_done = 1;
return;
}
Expand Down Expand Up @@ -909,7 +911,7 @@ static void ev3_uart_handle_rx_data(struct work_struct *work)
err_invalid_state:
port->synced = 0;
port->new_baud_rate = EV3_UART_SPEED_MIN;
schedule_work(&port->change_bitrate_work);
queue_work(port->wq, &port->change_bitrate_work);
}

static int ev3_uart_open(struct tty_struct *tty)
Expand All @@ -922,6 +924,12 @@ static int ev3_uart_open(struct tty_struct *tty)
if (!port)
return -ENOMEM;

port->wq = create_singlethread_workqueue("ev3-uart");
if (!port->wq) {
kfree(port);
return -ENOMEM;
}

port->tty = tty;
port->new_baud_rate = EV3_UART_SPEED_MIN;
port->type_id = EV3_UART_TYPE_UNKNOWN;
Expand Down Expand Up @@ -1013,6 +1021,7 @@ static void ev3_uart_close(struct tty_struct *tty)
if (port->in_port)
put_device(&port->in_port->dev);
tty->disc_data = NULL;
destroy_workqueue(port->wq);
kfree(port);
}

Expand Down Expand Up @@ -1045,7 +1054,7 @@ static void ev3_uart_receive_buf(struct tty_struct *tty,
cb->head += count;
}

schedule_work(&port->rx_data_work);
queue_work(port->wq, &port->rx_data_work);
}

static void ev3_uart_write_wakeup(struct tty_struct *tty)
Expand Down

0 comments on commit fa0d807

Please sign in to comment.