diff options
| author | Alexander Shiyan <shc_work@mail.ru> | 2014-02-07 09:16:07 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-13 12:33:05 -0500 |
| commit | e7b8a3ceff5e5c4e2bd329717976b18ce033d7cd (patch) | |
| tree | 5ea3a44d2893ef887e3ae84e6534f29ec31be636 | |
| parent | f4fcc40b564dd1920029053be9c4dd557b23a7ec (diff) | |
serial: max310x: Add the loopback mode support
This patch replaces loopback mode support from platform data to
dynamic setup with TIOCMSET ioctl.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/tty/serial/max310x.c | 25 | ||||
| -rw-r--r-- | include/linux/platform_data/max310x.h | 1 |
2 files changed, 18 insertions, 8 deletions
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 1fb3895a0a3a..3c93814b1648 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
| @@ -283,6 +283,7 @@ struct max310x_devtype { | |||
| 283 | struct max310x_one { | 283 | struct max310x_one { |
| 284 | struct uart_port port; | 284 | struct uart_port port; |
| 285 | struct work_struct tx_work; | 285 | struct work_struct tx_work; |
| 286 | struct work_struct md_work; | ||
| 286 | }; | 287 | }; |
| 287 | 288 | ||
| 288 | struct max310x_port { | 289 | struct max310x_port { |
| @@ -790,11 +791,21 @@ static unsigned int max310x_get_mctrl(struct uart_port *port) | |||
| 790 | return TIOCM_DSR | TIOCM_CAR; | 791 | return TIOCM_DSR | TIOCM_CAR; |
| 791 | } | 792 | } |
| 792 | 793 | ||
| 794 | static void max310x_md_proc(struct work_struct *ws) | ||
| 795 | { | ||
| 796 | struct max310x_one *one = container_of(ws, struct max310x_one, md_work); | ||
| 797 | |||
| 798 | max310x_port_update(&one->port, MAX310X_MODE2_REG, | ||
| 799 | MAX310X_MODE2_LOOPBACK_BIT, | ||
| 800 | (one->port.mctrl & TIOCM_LOOP) ? | ||
| 801 | MAX310X_MODE2_LOOPBACK_BIT : 0); | ||
| 802 | } | ||
| 803 | |||
| 793 | static void max310x_set_mctrl(struct uart_port *port, unsigned int mctrl) | 804 | static void max310x_set_mctrl(struct uart_port *port, unsigned int mctrl) |
| 794 | { | 805 | { |
| 795 | /* DCD and DSR are not wired and CTS/RTS is hadnled automatically | 806 | struct max310x_one *one = container_of(port, struct max310x_one, port); |
| 796 | * so do nothing | 807 | |
| 797 | */ | 808 | schedule_work(&one->md_work); |
| 798 | } | 809 | } |
| 799 | 810 | ||
| 800 | static void max310x_break_ctl(struct uart_port *port, int break_state) | 811 | static void max310x_break_ctl(struct uart_port *port, int break_state) |
| @@ -904,8 +915,6 @@ static int max310x_startup(struct uart_port *port) | |||
| 904 | 915 | ||
| 905 | /* Configure MODE2 register */ | 916 | /* Configure MODE2 register */ |
| 906 | val = MAX310X_MODE2_RXEMPTINV_BIT; | 917 | val = MAX310X_MODE2_RXEMPTINV_BIT; |
| 907 | if (s->pdata->uart_flags[line] & MAX310X_LOOPBACK) | ||
| 908 | val |= MAX310X_MODE2_LOOPBACK_BIT; | ||
| 909 | if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS) | 918 | if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS) |
| 910 | val |= MAX310X_MODE2_ECHOSUPR_BIT; | 919 | val |= MAX310X_MODE2_ECHOSUPR_BIT; |
| 911 | 920 | ||
| @@ -1176,8 +1185,7 @@ static int max310x_probe(struct device *dev, int is_spi, | |||
| 1176 | s->p[i].port.irq = irq; | 1185 | s->p[i].port.irq = irq; |
| 1177 | s->p[i].port.type = PORT_MAX310X; | 1186 | s->p[i].port.type = PORT_MAX310X; |
| 1178 | s->p[i].port.fifosize = MAX310X_FIFO_SIZE; | 1187 | s->p[i].port.fifosize = MAX310X_FIFO_SIZE; |
| 1179 | s->p[i].port.flags = UPF_SKIP_TEST | UPF_FIXED_TYPE | | 1188 | s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; |
| 1180 | UPF_LOW_LATENCY; | ||
| 1181 | s->p[i].port.iotype = UPIO_PORT; | 1189 | s->p[i].port.iotype = UPIO_PORT; |
| 1182 | s->p[i].port.iobase = i * 0x20; | 1190 | s->p[i].port.iobase = i * 0x20; |
| 1183 | s->p[i].port.membase = (void __iomem *)~0; | 1191 | s->p[i].port.membase = (void __iomem *)~0; |
| @@ -1193,6 +1201,8 @@ static int max310x_probe(struct device *dev, int is_spi, | |||
| 1193 | MAX310X_MODE1_IRQSEL_BIT); | 1201 | MAX310X_MODE1_IRQSEL_BIT); |
| 1194 | /* Initialize queue for start TX */ | 1202 | /* Initialize queue for start TX */ |
| 1195 | INIT_WORK(&s->p[i].tx_work, max310x_wq_proc); | 1203 | INIT_WORK(&s->p[i].tx_work, max310x_wq_proc); |
| 1204 | /* Initialize queue for changing mode */ | ||
| 1205 | INIT_WORK(&s->p[i].md_work, max310x_md_proc); | ||
| 1196 | /* Register port */ | 1206 | /* Register port */ |
| 1197 | uart_add_one_port(&s->uart, &s->p[i].port); | 1207 | uart_add_one_port(&s->uart, &s->p[i].port); |
| 1198 | /* Go to suspend mode */ | 1208 | /* Go to suspend mode */ |
| @@ -1244,6 +1254,7 @@ static int max310x_remove(struct device *dev) | |||
| 1244 | 1254 | ||
| 1245 | for (i = 0; i < s->uart.nr; i++) { | 1255 | for (i = 0; i < s->uart.nr; i++) { |
| 1246 | cancel_work_sync(&s->p[i].tx_work); | 1256 | cancel_work_sync(&s->p[i].tx_work); |
| 1257 | cancel_work_sync(&s->p[i].md_work); | ||
| 1247 | uart_remove_one_port(&s->uart, &s->p[i].port); | 1258 | uart_remove_one_port(&s->uart, &s->p[i].port); |
| 1248 | s->devtype->power(&s->p[i].port, 0); | 1259 | s->devtype->power(&s->p[i].port, 0); |
| 1249 | } | 1260 | } |
diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h index 5f4b35d99c2e..9d5f69b2b57c 100644 --- a/include/linux/platform_data/max310x.h +++ b/include/linux/platform_data/max310x.h | |||
| @@ -46,7 +46,6 @@ struct max310x_pdata { | |||
| 46 | #define MAX310X_EXT_CLK (0x00000001) /* External clock enable */ | 46 | #define MAX310X_EXT_CLK (0x00000001) /* External clock enable */ |
| 47 | /* Flags global to UART port */ | 47 | /* Flags global to UART port */ |
| 48 | const u8 uart_flags[MAX310X_MAX_UARTS]; | 48 | const u8 uart_flags[MAX310X_MAX_UARTS]; |
| 49 | #define MAX310X_LOOPBACK (0x00000001) /* Loopback mode enable */ | ||
| 50 | #define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ | 49 | #define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ |
| 51 | #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction | 50 | #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction |
| 52 | * control (RS-485) | 51 | * control (RS-485) |
