diff options
| author | Alexander Shiyan <shc_work@mail.ru> | 2014-02-10 13:18:34 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-13 12:34:48 -0500 |
| commit | 55367c620aed6bc27a82bb1763366931d7f2ee66 (patch) | |
| tree | b61316e9f2e13061aa3d2cf28175886c5853c0fd | |
| parent | 0fbae8874eea124591aee10efae98d244a2d072d (diff) | |
serial: max310x: Add support for RS-485 mode
This patch adds support for RS-485 (TIOCSRS485/TIOCGRS485) IOCTLs.
As a result this patch eliminate private driver header.
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 | 77 | ||||
| -rw-r--r-- | include/linux/platform_data/max310x.h | 49 |
2 files changed, 56 insertions, 70 deletions
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index c180576546ed..090f25d4a019 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
| @@ -26,8 +26,6 @@ | |||
| 26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
| 27 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
| 28 | 28 | ||
| 29 | #include <linux/platform_data/max310x.h> | ||
| 30 | |||
| 31 | #define MAX310X_NAME "max310x" | 29 | #define MAX310X_NAME "max310x" |
| 32 | #define MAX310X_MAJOR 204 | 30 | #define MAX310X_MAJOR 204 |
| 33 | #define MAX310X_MINOR 209 | 31 | #define MAX310X_MINOR 209 |
| @@ -293,7 +291,6 @@ struct max310x_port { | |||
| 293 | struct regmap *regmap; | 291 | struct regmap *regmap; |
| 294 | struct mutex mutex; | 292 | struct mutex mutex; |
| 295 | struct clk *clk; | 293 | struct clk *clk; |
| 296 | struct max310x_pdata *pdata; | ||
| 297 | #ifdef CONFIG_GPIOLIB | 294 | #ifdef CONFIG_GPIOLIB |
| 298 | struct gpio_chip gpio; | 295 | struct gpio_chip gpio; |
| 299 | #endif | 296 | #endif |
| @@ -898,26 +895,70 @@ static void max310x_set_termios(struct uart_port *port, | |||
| 898 | uart_update_timeout(port, termios->c_cflag, baud); | 895 | uart_update_timeout(port, termios->c_cflag, baud); |
| 899 | } | 896 | } |
| 900 | 897 | ||
| 898 | static int max310x_ioctl(struct uart_port *port, unsigned int cmd, | ||
| 899 | unsigned long arg) | ||
| 900 | { | ||
| 901 | struct serial_rs485 rs485; | ||
| 902 | unsigned int val; | ||
| 903 | |||
| 904 | switch (cmd) { | ||
| 905 | case TIOCSRS485: | ||
| 906 | if (copy_from_user(&rs485, (struct serial_rs485 *)arg, | ||
| 907 | sizeof(rs485))) | ||
| 908 | return -EFAULT; | ||
| 909 | if (rs485.delay_rts_before_send > 0x0f || | ||
| 910 | rs485.delay_rts_after_send > 0x0f) | ||
| 911 | return -ERANGE; | ||
| 912 | val = (rs485.delay_rts_before_send << 4) | | ||
| 913 | rs485.delay_rts_after_send; | ||
| 914 | max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val); | ||
| 915 | if (rs485.flags & SER_RS485_ENABLED) { | ||
| 916 | max310x_port_update(port, MAX310X_MODE1_REG, | ||
| 917 | MAX310X_MODE1_TRNSCVCTRL_BIT, | ||
| 918 | MAX310X_MODE1_TRNSCVCTRL_BIT); | ||
| 919 | max310x_port_update(port, MAX310X_MODE2_REG, | ||
| 920 | MAX310X_MODE2_ECHOSUPR_BIT, | ||
| 921 | MAX310X_MODE2_ECHOSUPR_BIT); | ||
| 922 | } else { | ||
| 923 | max310x_port_update(port, MAX310X_MODE1_REG, | ||
| 924 | MAX310X_MODE1_TRNSCVCTRL_BIT, 0); | ||
| 925 | max310x_port_update(port, MAX310X_MODE2_REG, | ||
| 926 | MAX310X_MODE2_ECHOSUPR_BIT, 0); | ||
| 927 | } | ||
| 928 | break; | ||
| 929 | case TIOCGRS485: | ||
| 930 | memset(&rs485, 0, sizeof(rs485)); | ||
| 931 | val = max310x_port_read(port, MAX310X_MODE1_REG); | ||
| 932 | rs485.flags = (val & MAX310X_MODE1_TRNSCVCTRL_BIT) ? | ||
| 933 | SER_RS485_ENABLED : 0; | ||
| 934 | rs485.flags |= SER_RS485_RTS_ON_SEND; | ||
| 935 | val = max310x_port_read(port, MAX310X_HDPIXDELAY_REG); | ||
| 936 | rs485.delay_rts_before_send = val >> 4; | ||
| 937 | rs485.delay_rts_after_send = val & 0x0f; | ||
| 938 | if (copy_to_user((struct serial_rs485 *)arg, &rs485, | ||
| 939 | sizeof(rs485))) | ||
| 940 | return -EFAULT; | ||
| 941 | break; | ||
| 942 | default: | ||
| 943 | return -ENOIOCTLCMD; | ||
| 944 | } | ||
| 945 | |||
| 946 | return 0; | ||
| 947 | } | ||
| 948 | |||
| 901 | static int max310x_startup(struct uart_port *port) | 949 | static int max310x_startup(struct uart_port *port) |
| 902 | { | 950 | { |
| 903 | unsigned int val, line = port->line; | ||
| 904 | struct max310x_port *s = dev_get_drvdata(port->dev); | 951 | struct max310x_port *s = dev_get_drvdata(port->dev); |
| 952 | unsigned int val; | ||
| 905 | 953 | ||
| 906 | s->devtype->power(port, 1); | 954 | s->devtype->power(port, 1); |
| 907 | 955 | ||
| 908 | /* Configure MODE1 register */ | 956 | /* Configure MODE1 register */ |
| 909 | max310x_port_update(port, MAX310X_MODE1_REG, | 957 | max310x_port_update(port, MAX310X_MODE1_REG, |
| 910 | MAX310X_MODE1_TRNSCVCTRL_BIT, | 958 | MAX310X_MODE1_TRNSCVCTRL_BIT, 0); |
| 911 | (s->pdata->uart_flags[line] & MAX310X_AUTO_DIR_CTRL) | ||
| 912 | ? MAX310X_MODE1_TRNSCVCTRL_BIT : 0); | ||
| 913 | 959 | ||
| 914 | /* Configure MODE2 register */ | 960 | /* Configure MODE2 register & Reset FIFOs*/ |
| 915 | val = MAX310X_MODE2_RXEMPTINV_BIT; | 961 | val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT; |
| 916 | if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS) | ||
| 917 | val |= MAX310X_MODE2_ECHOSUPR_BIT; | ||
| 918 | |||
| 919 | /* Reset FIFOs */ | ||
| 920 | val |= MAX310X_MODE2_FIFORST_BIT; | ||
| 921 | max310x_port_write(port, MAX310X_MODE2_REG, val); | 962 | max310x_port_write(port, MAX310X_MODE2_REG, val); |
| 922 | max310x_port_update(port, MAX310X_MODE2_REG, | 963 | max310x_port_update(port, MAX310X_MODE2_REG, |
| 923 | MAX310X_MODE2_FIFORST_BIT, 0); | 964 | MAX310X_MODE2_FIFORST_BIT, 0); |
| @@ -998,6 +1039,7 @@ static const struct uart_ops max310x_ops = { | |||
| 998 | .release_port = max310x_null_void, | 1039 | .release_port = max310x_null_void, |
| 999 | .config_port = max310x_config_port, | 1040 | .config_port = max310x_config_port, |
| 1000 | .verify_port = max310x_verify_port, | 1041 | .verify_port = max310x_verify_port, |
| 1042 | .ioctl = max310x_ioctl, | ||
| 1001 | }; | 1043 | }; |
| 1002 | 1044 | ||
| 1003 | static int __maybe_unused max310x_suspend(struct device *dev) | 1045 | static int __maybe_unused max310x_suspend(struct device *dev) |
| @@ -1077,7 +1119,6 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip, | |||
| 1077 | static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | 1119 | static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, |
| 1078 | struct regmap *regmap, int irq) | 1120 | struct regmap *regmap, int irq) |
| 1079 | { | 1121 | { |
| 1080 | struct max310x_pdata *pdata = dev_get_platdata(dev); | ||
| 1081 | int i, ret, fmin, fmax, freq, uartclk; | 1122 | int i, ret, fmin, fmax, freq, uartclk; |
| 1082 | struct clk *clk_osc, *clk_xtal; | 1123 | struct clk *clk_osc, *clk_xtal; |
| 1083 | struct max310x_port *s; | 1124 | struct max310x_port *s; |
| @@ -1086,11 +1127,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
| 1086 | if (IS_ERR(regmap)) | 1127 | if (IS_ERR(regmap)) |
| 1087 | return PTR_ERR(regmap); | 1128 | return PTR_ERR(regmap); |
| 1088 | 1129 | ||
| 1089 | if (!pdata) { | ||
| 1090 | dev_err(dev, "No platform data supplied\n"); | ||
| 1091 | return -EINVAL; | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | /* Alloc port structure */ | 1130 | /* Alloc port structure */ |
| 1095 | s = devm_kzalloc(dev, sizeof(*s) + | 1131 | s = devm_kzalloc(dev, sizeof(*s) + |
| 1096 | sizeof(struct max310x_one) * devtype->nr, GFP_KERNEL); | 1132 | sizeof(struct max310x_one) * devtype->nr, GFP_KERNEL); |
| @@ -1129,7 +1165,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
| 1129 | goto out_clk; | 1165 | goto out_clk; |
| 1130 | } | 1166 | } |
| 1131 | 1167 | ||
| 1132 | s->pdata = pdata; | ||
| 1133 | s->regmap = regmap; | 1168 | s->regmap = regmap; |
| 1134 | s->devtype = devtype; | 1169 | s->devtype = devtype; |
| 1135 | dev_set_drvdata(dev, s); | 1170 | dev_set_drvdata(dev, s); |
diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h deleted file mode 100644 index 1140a57e735f..000000000000 --- a/include/linux/platform_data/max310x.h +++ /dev/null | |||
| @@ -1,49 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
| 5 | * | ||
| 6 | * Based on max3100.c, by Christian Pellegrin <chripell@evolware.org> | ||
| 7 | * Based on max3110.c, by Feng Tang <feng.tang@intel.com> | ||
| 8 | * Based on max3107.c, by Aavamobile | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #ifndef _MAX310X_H_ | ||
| 17 | #define _MAX310X_H_ | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Example board initialization data: | ||
| 21 | * | ||
| 22 | * static struct max310x_pdata max3107_pdata = { | ||
| 23 | * .uart_flags[0] = MAX310X_ECHO_SUPRESS | MAX310X_AUTO_DIR_CTRL, | ||
| 24 | * }; | ||
| 25 | * | ||
| 26 | * static struct spi_board_info spi_device_max3107[] = { | ||
| 27 | * { | ||
| 28 | * .modalias = "max3107", | ||
| 29< | |||
