diff options
author | Ulrich Hecht <ulrich.hecht+renesas@gmail.com> | 2018-01-22 12:56:32 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2018-01-23 03:16:05 -0500 |
commit | 3a19cfcce105e481b02b14265c5b40c6c10ef60a (patch) | |
tree | ffd4e503a4e231247334fbfb8cd1c0eaae635e6d | |
parent | 8c6b8eda7294775097e0d0eb64cb6f86d460d7c2 (diff) |
serdev: add method to set parity
Adds serdev_device_set_parity() and an implementation for ttyport.
The interface uses an enum with the values SERIAL_PARITY_NONE,
SERIAL_PARITY_EVEN and SERIAL_PARITY_ODD.
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Reviewed-by: Johan Hovold <johan@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | drivers/tty/serdev/core.c | 12 | ||||
-rw-r--r-- | drivers/tty/serdev/serdev-ttyport.c | 24 | ||||
-rw-r--r-- | include/linux/serdev.h | 10 |
3 files changed, 46 insertions, 0 deletions
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 1bef39828ca7..3c573a8caa80 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c | |||
@@ -225,6 +225,18 @@ void serdev_device_set_flow_control(struct serdev_device *serdev, bool enable) | |||
225 | } | 225 | } |
226 | EXPORT_SYMBOL_GPL(serdev_device_set_flow_control); | 226 | EXPORT_SYMBOL_GPL(serdev_device_set_flow_control); |
227 | 227 | ||
228 | int serdev_device_set_parity(struct serdev_device *serdev, | ||
229 | enum serdev_parity parity) | ||
230 | { | ||
231 | struct serdev_controller *ctrl = serdev->ctrl; | ||
232 | |||
233 | if (!ctrl || !ctrl->ops->set_parity) | ||
234 | return -ENOTSUPP; | ||
235 | |||
236 | return ctrl->ops->set_parity(ctrl, parity); | ||
237 | } | ||
238 | EXPORT_SYMBOL_GPL(serdev_device_set_parity); | ||
239 | |||
228 | void serdev_device_wait_until_sent(struct serdev_device *serdev, long timeout) | 240 | void serdev_device_wait_until_sent(struct serdev_device *serdev, long timeout) |
229 | { | 241 | { |
230 | struct serdev_controller *ctrl = serdev->ctrl; | 242 | struct serdev_controller *ctrl = serdev->ctrl; |
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index 247788a16f0b..1bdf2959ac5c 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c | |||
@@ -190,6 +190,29 @@ static void ttyport_set_flow_control(struct serdev_controller *ctrl, bool enable | |||
190 | tty_set_termios(tty, &ktermios); | 190 | tty_set_termios(tty, &ktermios); |
191 | } | 191 | } |
192 | 192 | ||
193 | static int ttyport_set_parity(struct serdev_controller *ctrl, | ||
194 | enum serdev_parity parity) | ||
195 | { | ||
196 | struct serport *serport = serdev_controller_get_drvdata(ctrl); | ||
197 | struct tty_struct *tty = serport->tty; | ||
198 | struct ktermios ktermios = tty->termios; | ||
199 | |||
200 | ktermios.c_cflag &= ~(PARENB | PARODD | CMSPAR); | ||
201 | if (parity != SERDEV_PARITY_NONE) { | ||
202 | ktermios.c_cflag |= PARENB; | ||
203 | if (parity == SERDEV_PARITY_ODD) | ||
204 | ktermios.c_cflag |= PARODD; | ||
205 | } | ||
206 | |||
207 | tty_set_termios(tty, &ktermios); | ||
208 | |||
209 | if ((tty->termios.c_cflag & (PARENB | PARODD | CMSPAR)) != | ||
210 | (ktermios.c_cflag & (PARENB | PARODD | CMSPAR))) | ||
211 | return -EINVAL; | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
193 | static void ttyport_wait_until_sent(struct serdev_controller *ctrl, long timeout) | 216 | static void ttyport_wait_until_sent(struct serdev_controller *ctrl, long timeout) |
194 | { | 217 | { |
195 | struct serport *serport = serdev_controller_get_drvdata(ctrl); | 218 | struct serport *serport = serdev_controller_get_drvdata(ctrl); |
@@ -227,6 +250,7 @@ static const struct serdev_controller_ops ctrl_ops = { | |||
227 | .open = ttyport_open, | 250 | .open = ttyport_open, |
228 | .close = ttyport_close, | 251 | .close = ttyport_close, |
229 | .set_flow_control = ttyport_set_flow_control, | 252 | .set_flow_control = ttyport_set_flow_control, |
253 | .set_parity = ttyport_set_parity, | ||
230 | .set_baudrate = ttyport_set_baudrate, | 254 | .set_baudrate = ttyport_set_baudrate, |
231 | .wait_until_sent = ttyport_wait_until_sent, | 255 | .wait_until_sent = ttyport_wait_until_sent, |
232 | .get_tiocm = ttyport_get_tiocm, | 256 | .get_tiocm = ttyport_get_tiocm, |
diff --git a/include/linux/serdev.h b/include/linux/serdev.h index d609e6dc5bad..a73d87b483b4 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h | |||
@@ -76,6 +76,12 @@ static inline struct serdev_device_driver *to_serdev_device_driver(struct device | |||
76 | return container_of(d, struct serdev_device_driver, driver); | 76 | return container_of(d, struct serdev_device_driver, driver); |
77 | } | 77 | } |
78 | 78 | ||
79 | enum serdev_parity { | ||
80 | SERDEV_PARITY_NONE, | ||
81 | SERDEV_PARITY_EVEN, | ||
82 | SERDEV_PARITY_ODD, | ||
83 | }; | ||
84 | |||
79 | /* | 85 | /* |
80 | * serdev controller structures | 86 | * serdev controller structures |
81 | */ | 87 | */ |
@@ -86,6 +92,7 @@ struct serdev_controller_ops { | |||
86 | int (*open)(struct serdev_controller *); | 92 | int (*open)(struct serdev_controller *); |
87 | void (*close)(struct serdev_controller *); | 93 | void (*close)(struct serdev_controller *); |
88 | void (*set_flow_control)(struct serdev_controller *, bool); | 94 | void (*set_flow_control)(struct serdev_controller *, bool); |
95 | int (*set_parity)(struct serdev_controller *, enum serdev_parity); | ||
89 | unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int); | 96 | unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int); |
90 | void (*wait_until_sent)(struct serdev_controller *, long); | 97 | void (*wait_until_sent)(struct serdev_controller *, long); |
91 | int (*get_tiocm)(struct serdev_controller *); | 98 | int (*get_tiocm)(struct serdev_controller *); |
@@ -298,6 +305,9 @@ static inline int serdev_device_set_rts(struct serdev_device *serdev, bool enabl | |||
298 | return serdev_device_set_tiocm(serdev, 0, TIOCM_RTS); | 305 | return serdev_device_set_tiocm(serdev, 0, TIOCM_RTS); |
299 | } | 306 | } |
300 | 307 | ||
308 | int serdev_device_set_parity(struct serdev_device *serdev, | ||
309 | enum serdev_parity parity); | ||
310 | |||
301 | /* | 311 | /* |
302 | * serdev hooks into TTY core | 312 | * serdev hooks into TTY core |
303 | */ | 313 | */ |