From 1e6128b63597adf97f1865fba7d778a6f8ccb7a0 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Fri, 7 Feb 2014 18:16:05 +0400 Subject: serial: max310x: Remove init() and exit() callbacks These callbacks were previously used for the IC power initialization. If this initialization will be needed in the future, it should be implemented with the regulator API. Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- include/linux/platform_data/max310x.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h index dd11dcd1a184..5f4b35d99c2e 100644 --- a/include/linux/platform_data/max310x.h +++ b/include/linux/platform_data/max310x.h @@ -55,10 +55,6 @@ struct max310x_pdata { const int frequency; /* GPIO base number (can be negative) */ const int gpio_base; - /* Called during startup */ - void (*init)(void); - /* Called before finish */ - void (*exit)(void); }; #endif -- cgit v1.3.1 From e7b8a3ceff5e5c4e2bd329717976b18ce033d7cd Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Fri, 7 Feb 2014 18:16:07 +0400 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 25 ++++++++++++++++++------- include/linux/platform_data/max310x.h | 1 - 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'include') 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 { struct max310x_one { struct uart_port port; struct work_struct tx_work; + struct work_struct md_work; }; struct max310x_port { @@ -790,11 +791,21 @@ static unsigned int max310x_get_mctrl(struct uart_port *port) return TIOCM_DSR | TIOCM_CAR; } +static void max310x_md_proc(struct work_struct *ws) +{ + struct max310x_one *one = container_of(ws, struct max310x_one, md_work); + + max310x_port_update(&one->port, MAX310X_MODE2_REG, + MAX310X_MODE2_LOOPBACK_BIT, + (one->port.mctrl & TIOCM_LOOP) ? + MAX310X_MODE2_LOOPBACK_BIT : 0); +} + static void max310x_set_mctrl(struct uart_port *port, unsigned int mctrl) { - /* DCD and DSR are not wired and CTS/RTS is hadnled automatically - * so do nothing - */ + struct max310x_one *one = container_of(port, struct max310x_one, port); + + schedule_work(&one->md_work); } static void max310x_break_ctl(struct uart_port *port, int break_state) @@ -904,8 +915,6 @@ static int max310x_startup(struct uart_port *port) /* Configure MODE2 register */ val = MAX310X_MODE2_RXEMPTINV_BIT; - if (s->pdata->uart_flags[line] & MAX310X_LOOPBACK) - val |= MAX310X_MODE2_LOOPBACK_BIT; if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS) val |= MAX310X_MODE2_ECHOSUPR_BIT; @@ -1176,8 +1185,7 @@ static int max310x_probe(struct device *dev, int is_spi, s->p[i].port.irq = irq; s->p[i].port.type = PORT_MAX310X; s->p[i].port.fifosize = MAX310X_FIFO_SIZE; - s->p[i].port.flags = UPF_SKIP_TEST | UPF_FIXED_TYPE | - UPF_LOW_LATENCY; + s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY; s->p[i].port.iotype = UPIO_PORT; s->p[i].port.iobase = i * 0x20; s->p[i].port.membase = (void __iomem *)~0; @@ -1193,6 +1201,8 @@ static int max310x_probe(struct device *dev, int is_spi, MAX310X_MODE1_IRQSEL_BIT); /* Initialize queue for start TX */ INIT_WORK(&s->p[i].tx_work, max310x_wq_proc); + /* Initialize queue for changing mode */ + INIT_WORK(&s->p[i].md_work, max310x_md_proc); /* Register port */ uart_add_one_port(&s->uart, &s->p[i].port); /* Go to suspend mode */ @@ -1244,6 +1254,7 @@ static int max310x_remove(struct device *dev) for (i = 0; i < s->uart.nr; i++) { cancel_work_sync(&s->p[i].tx_work); + cancel_work_sync(&s->p[i].md_work); uart_remove_one_port(&s->uart, &s->p[i].port); s->devtype->power(&s->p[i].port, 0); } 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 { #define MAX310X_EXT_CLK (0x00000001) /* External clock enable */ /* Flags global to UART port */ const u8 uart_flags[MAX310X_MAX_UARTS]; -#define MAX310X_LOOPBACK (0x00000001) /* Loopback mode enable */ #define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction * control (RS-485) -- cgit v1.3.1 From d3a8a252e177cfaa2fb04120dd944104e4417bf5 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 10 Feb 2014 22:18:31 +0400 Subject: serial: max310x: Migrate to CLK API This patch removes "frequency" parameter from MAX310X platform_data and uses CLK API for getting clock. Clock type (XTAL/OSC) is determined by clk name. Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 86 ++++++++++++++++++++++------------- include/linux/platform_data/max310x.h | 7 --- 2 files changed, 55 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 9e147f3d7291..310ee555fade 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -291,6 +292,7 @@ struct max310x_port { struct max310x_devtype *devtype; struct regmap *regmap; struct mutex mutex; + struct clk *clk; struct max310x_pdata *pdata; int gpio_used; #ifdef CONFIG_GPIOLIB @@ -546,18 +548,19 @@ static int max310x_update_best_err(unsigned long f, long *besterr) return 1; } -static int max310x_set_ref_clk(struct max310x_port *s) +static int max310x_set_ref_clk(struct max310x_port *s, unsigned long freq, + bool xtal) { unsigned int div, clksrc, pllcfg = 0; long besterr = -1; - unsigned long fdiv, fmul, bestfreq = s->pdata->frequency; + unsigned long fdiv, fmul, bestfreq = freq; /* First, update error without PLL */ - max310x_update_best_err(s->pdata->frequency, &besterr); + max310x_update_best_err(freq, &besterr); /* Try all possible PLL dividers */ for (div = 1; (div <= 63) && besterr; div++) { - fdiv = DIV_ROUND_CLOSEST(s->pdata->frequency, div); + fdiv = DIV_ROUND_CLOSEST(freq, div); /* Try multiplier 6 */ fmul = fdiv * 6; @@ -590,10 +593,7 @@ static int max310x_set_ref_clk(struct max310x_port *s) } /* Configure clock source */ - if (s->pdata->driver_flags & MAX310X_EXT_CLK) - clksrc = MAX310X_CLKSRC_EXTCLK_BIT; - else - clksrc = MAX310X_CLKSRC_CRYST_BIT; + clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT; /* Configure PLL */ if (pllcfg) { @@ -605,7 +605,7 @@ static int max310x_set_ref_clk(struct max310x_port *s) regmap_write(s->regmap, MAX310X_CLKSRC_REG, clksrc); /* Wait for crystal */ - if (pllcfg && !(s->pdata->driver_flags & MAX310X_EXT_CLK)) + if (pllcfg && xtal) msleep(10); return (int)bestfreq; @@ -1078,9 +1078,11 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip, static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, struct regmap *regmap, int irq) { - struct max310x_port *s; struct max310x_pdata *pdata = dev_get_platdata(dev); - int i, ret, uartclk; + int i, ret, fmin, fmax, freq, uartclk; + struct clk *clk_osc, *clk_xtal; + struct max310x_port *s; + bool xtal = false; if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -1098,14 +1100,35 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, return -ENOMEM; } - /* Check input frequency */ - if ((pdata->driver_flags & MAX310X_EXT_CLK) && - ((pdata->frequency < 500000) || (pdata->frequency > 35000000))) - goto err_freq; - /* Check frequency for quartz */ - if (!(pdata->driver_flags & MAX310X_EXT_CLK) && - ((pdata->frequency < 1000000) || (pdata->frequency > 4000000))) - goto err_freq; + clk_osc = devm_clk_get(dev, "osc"); + clk_xtal = devm_clk_get(dev, "xtal"); + if (!IS_ERR(clk_osc)) { + s->clk = clk_osc; + fmin = 500000; + fmax = 35000000; + } else if (!IS_ERR(clk_xtal)) { + s->clk = clk_xtal; + fmin = 1000000; + fmax = 4000000; + xtal = true; + } else if (PTR_ERR(clk_osc) == -EPROBE_DEFER || + PTR_ERR(clk_xtal) == -EPROBE_DEFER) { + return -EPROBE_DEFER; + } else { + dev_err(dev, "Cannot get clock\n"); + return -EINVAL; + } + + ret = clk_prepare_enable(s->clk); + if (ret) + return ret; + + freq = clk_get_rate(s->clk); + /* Check frequency limits */ + if (freq < fmin || freq > fmax) { + ret = -ERANGE; + goto out_clk; + } s->pdata = pdata; s->regmap = regmap; @@ -1117,7 +1140,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, /* Check device to ensure we are talking to what we expect */ ret = devtype->detect(dev); if (ret) - return ret; + goto out_clk; for (i = 0; i < devtype->nr; i++) { unsigned int offs = i << 5; @@ -1139,7 +1162,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, MAX310X_MODE1_AUTOSLEEP_BIT); } - uartclk = max310x_set_ref_clk(s); + uartclk = max310x_set_ref_clk(s, freq, xtal); dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); /* Register UART driver */ @@ -1151,7 +1174,7 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, ret = uart_register_driver(&s->uart); if (ret) { dev_err(dev, "Registering UART driver failed\n"); - return ret; + goto out_clk; } for (i = 0; i < devtype->nr; i++) { @@ -1208,19 +1231,19 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), s); - if (ret) { - dev_err(dev, "Unable to reguest IRQ %i\n", irq); + if (!ret) + return 0; + + dev_err(dev, "Unable to reguest IRQ %i\n", irq); #ifdef CONFIG_GPIOLIB - if (s->gpio_used) - WARN_ON(gpiochip_remove(&s->gpio)); + if (s->gpio_used) + WARN_ON(gpiochip_remove(&s->gpio)); #endif - } - return ret; +out_clk: + clk_disable_unprepare(s->clk); -err_freq: - dev_err(dev, "Frequency parameter incorrect\n"); - return -EINVAL; + return ret; } static int max310x_remove(struct device *dev) @@ -1236,6 +1259,7 @@ static int max310x_remove(struct device *dev) } uart_unregister_driver(&s->uart); + clk_disable_unprepare(s->clk); #ifdef CONFIG_GPIOLIB if (s->gpio_used) diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h index 9d5f69b2b57c..57a0cd46b847 100644 --- a/include/linux/platform_data/max310x.h +++ b/include/linux/platform_data/max310x.h @@ -20,9 +20,7 @@ * Example board initialization data: * * static struct max310x_pdata max3107_pdata = { - * .driver_flags = MAX310X_EXT_CLK, * .uart_flags[0] = MAX310X_ECHO_SUPRESS | MAX310X_AUTO_DIR_CTRL, - * .frequency = 3686400, * .gpio_base = -1, * }; * @@ -41,17 +39,12 @@ /* MAX310X platform data structure */ struct max310x_pdata { - /* Flags global to driver */ - const u8 driver_flags; -#define MAX310X_EXT_CLK (0x00000001) /* External clock enable */ /* Flags global to UART port */ const u8 uart_flags[MAX310X_MAX_UARTS]; #define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction * control (RS-485) */ - /* Frequency (extrenal clock or crystal) */ - const int frequency; /* GPIO base number (can be negative) */ const int gpio_base; }; -- cgit v1.3.1 From dba29a2894771562d265232ae4b61f0310bab1f5 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 10 Feb 2014 22:18:32 +0400 Subject: serial: max310x: Always use dynamic GPIO ID assignment Always register GPIOs and use dynamic GPIO ID assignment. This is no much worth if GPIOs is not used, but helps remove private driver header and add DT support in the future. Additionally, patch adds missing uart_unregister_driver() call if probe() fails. Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 55 ++++++++++++++++++----------------- include/linux/platform_data/max310x.h | 3 -- 2 files changed, 28 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 310ee555fade..2a12cbcbf388 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -294,7 +294,6 @@ struct max310x_port { struct mutex mutex; struct clk *clk; struct max310x_pdata *pdata; - int gpio_used; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio; #endif @@ -1177,6 +1176,23 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, goto out_clk; } +#ifdef CONFIG_GPIOLIB + /* Setup GPIO cotroller */ + s->gpio.owner = THIS_MODULE; + s->gpio.dev = dev; + s->gpio.label = dev_name(dev); + s->gpio.direction_input = max310x_gpio_direction_input; + s->gpio.get = max310x_gpio_get; + s->gpio.direction_output= max310x_gpio_direction_output; + s->gpio.set = max310x_gpio_set; + s->gpio.base = -1; + s->gpio.ngpio = devtype->nr * 4; + s->gpio.can_sleep = 1; + ret = gpiochip_add(&s->gpio); + if (ret) + goto out_uart; +#endif + for (i = 0; i < devtype->nr; i++) { /* Initialize port data */ s->p[i].port.line = i; @@ -1208,25 +1224,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, devtype->power(&s->p[i].port, 0); } -#ifdef CONFIG_GPIOLIB - /* Setup GPIO cotroller */ - if (s->pdata->gpio_base) { - s->gpio.owner = THIS_MODULE; - s->gpio.dev = dev; - s->gpio.label = dev_name(dev); - s->gpio.direction_input = max310x_gpio_direction_input; - s->gpio.get = max310x_gpio_get; - s->gpio.direction_output= max310x_gpio_direction_output; - s->gpio.set = max310x_gpio_set; - s->gpio.base = s->pdata->gpio_base; - s->gpio.ngpio = devtype->nr * 4; - s->gpio.can_sleep = 1; - if (!gpiochip_add(&s->gpio)) - s->gpio_used = 1; - } else - dev_info(dev, "GPIO support not enabled\n"); -#endif - /* Setup interrupt */ ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, @@ -1235,11 +1232,14 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, return 0; dev_err(dev, "Unable to reguest IRQ %i\n", irq); + #ifdef CONFIG_GPIOLIB - if (s->gpio_used) - WARN_ON(gpiochip_remove(&s->gpio)); + WARN_ON(gpiochip_remove(&s->gpio)); #endif +out_uart: + uart_unregister_driver(&s->uart); + out_clk: clk_disable_unprepare(s->clk); @@ -1251,6 +1251,12 @@ static int max310x_remove(struct device *dev) struct max310x_port *s = dev_get_drvdata(dev); int i, ret = 0; +#ifdef CONFIG_GPIOLIB + ret = gpiochip_remove(&s->gpio); + if (ret) + return ret; +#endif + for (i = 0; i < s->uart.nr; i++) { cancel_work_sync(&s->p[i].tx_work); cancel_work_sync(&s->p[i].md_work); @@ -1261,11 +1267,6 @@ static int max310x_remove(struct device *dev) uart_unregister_driver(&s->uart); clk_disable_unprepare(s->clk); -#ifdef CONFIG_GPIOLIB - if (s->gpio_used) - ret = gpiochip_remove(&s->gpio); -#endif - return ret; } diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h index 57a0cd46b847..1140a57e735f 100644 --- a/include/linux/platform_data/max310x.h +++ b/include/linux/platform_data/max310x.h @@ -21,7 +21,6 @@ * * static struct max310x_pdata max3107_pdata = { * .uart_flags[0] = MAX310X_ECHO_SUPRESS | MAX310X_AUTO_DIR_CTRL, - * .gpio_base = -1, * }; * * static struct spi_board_info spi_device_max3107[] = { @@ -45,8 +44,6 @@ struct max310x_pdata { #define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction * control (RS-485) */ - /* GPIO base number (can be negative) */ - const int gpio_base; }; #endif -- cgit v1.3.1 From 55367c620aed6bc27a82bb1763366931d7f2ee66 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Mon, 10 Feb 2014 22:18:34 +0400 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 77 +++++++++++++++++++++++++---------- include/linux/platform_data/max310x.h | 49 ---------------------- 2 files changed, 56 insertions(+), 70 deletions(-) delete mode 100644 include/linux/platform_data/max310x.h (limited to 'include') 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 @@ #include #include -#include - #define MAX310X_NAME "max310x" #define MAX310X_MAJOR 204 #define MAX310X_MINOR 209 @@ -293,7 +291,6 @@ struct max310x_port { struct regmap *regmap; struct mutex mutex; struct clk *clk; - struct max310x_pdata *pdata; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio; #endif @@ -898,26 +895,70 @@ static void max310x_set_termios(struct uart_port *port, uart_update_timeout(port, termios->c_cflag, baud); } +static int max310x_ioctl(struct uart_port *port, unsigned int cmd, + unsigned long arg) +{ + struct serial_rs485 rs485; + unsigned int val; + + switch (cmd) { + case TIOCSRS485: + if (copy_from_user(&rs485, (struct serial_rs485 *)arg, + sizeof(rs485))) + return -EFAULT; + if (rs485.delay_rts_before_send > 0x0f || + rs485.delay_rts_after_send > 0x0f) + return -ERANGE; + val = (rs485.delay_rts_before_send << 4) | + rs485.delay_rts_after_send; + max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val); + if (rs485.flags & SER_RS485_ENABLED) { + max310x_port_update(port, MAX310X_MODE1_REG, + MAX310X_MODE1_TRNSCVCTRL_BIT, + MAX310X_MODE1_TRNSCVCTRL_BIT); + max310x_port_update(port, MAX310X_MODE2_REG, + MAX310X_MODE2_ECHOSUPR_BIT, + MAX310X_MODE2_ECHOSUPR_BIT); + } else { + max310x_port_update(port, MAX310X_MODE1_REG, + MAX310X_MODE1_TRNSCVCTRL_BIT, 0); + max310x_port_update(port, MAX310X_MODE2_REG, + MAX310X_MODE2_ECHOSUPR_BIT, 0); + } + break; + case TIOCGRS485: + memset(&rs485, 0, sizeof(rs485)); + val = max310x_port_read(port, MAX310X_MODE1_REG); + rs485.flags = (val & MAX310X_MODE1_TRNSCVCTRL_BIT) ? + SER_RS485_ENABLED : 0; + rs485.flags |= SER_RS485_RTS_ON_SEND; + val = max310x_port_read(port, MAX310X_HDPIXDELAY_REG); + rs485.delay_rts_before_send = val >> 4; + rs485.delay_rts_after_send = val & 0x0f; + if (copy_to_user((struct serial_rs485 *)arg, &rs485, + sizeof(rs485))) + return -EFAULT; + break; + default: + return -ENOIOCTLCMD; + } + + return 0; +} + static int max310x_startup(struct uart_port *port) { - unsigned int val, line = port->line; struct max310x_port *s = dev_get_drvdata(port->dev); + unsigned int val; s->devtype->power(port, 1); /* Configure MODE1 register */ max310x_port_update(port, MAX310X_MODE1_REG, - MAX310X_MODE1_TRNSCVCTRL_BIT, - (s->pdata->uart_flags[line] & MAX310X_AUTO_DIR_CTRL) - ? MAX310X_MODE1_TRNSCVCTRL_BIT : 0); + MAX310X_MODE1_TRNSCVCTRL_BIT, 0); - /* Configure MODE2 register */ - val = MAX310X_MODE2_RXEMPTINV_BIT; - if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS) - val |= MAX310X_MODE2_ECHOSUPR_BIT; - - /* Reset FIFOs */ - val |= MAX310X_MODE2_FIFORST_BIT; + /* Configure MODE2 register & Reset FIFOs*/ + val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT; max310x_port_write(port, MAX310X_MODE2_REG, val); max310x_port_update(port, MAX310X_MODE2_REG, MAX310X_MODE2_FIFORST_BIT, 0); @@ -998,6 +1039,7 @@ static const struct uart_ops max310x_ops = { .release_port = max310x_null_void, .config_port = max310x_config_port, .verify_port = max310x_verify_port, + .ioctl = max310x_ioctl, }; static int __maybe_unused max310x_suspend(struct device *dev) @@ -1077,7 +1119,6 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip, static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, struct regmap *regmap, int irq) { - struct max310x_pdata *pdata = dev_get_platdata(dev); int i, ret, fmin, fmax, freq, uartclk; struct clk *clk_osc, *clk_xtal; struct max310x_port *s; @@ -1086,11 +1127,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, if (IS_ERR(regmap)) return PTR_ERR(regmap); - if (!pdata) { - dev_err(dev, "No platform data supplied\n"); - return -EINVAL; - } - /* Alloc port structure */ s = devm_kzalloc(dev, sizeof(*s) + sizeof(struct max310x_one) * devtype->nr, GFP_KERNEL); @@ -1129,7 +1165,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, goto out_clk; } - s->pdata = pdata; s->regmap = regmap; s->devtype = devtype; 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 @@ -/* - * Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver - * - * Copyright (C) 2012 Alexander Shiyan - * - * Based on max3100.c, by Christian Pellegrin - * Based on max3110.c, by Feng Tang - * Based on max3107.c, by Aavamobile - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef _MAX310X_H_ -#define _MAX310X_H_ - -/* - * Example board initialization data: - * - * static struct max310x_pdata max3107_pdata = { - * .uart_flags[0] = MAX310X_ECHO_SUPRESS | MAX310X_AUTO_DIR_CTRL, - * }; - * - * static struct spi_board_info spi_device_max3107[] = { - * { - * .modalias = "max3107", - * .irq = IRQ_EINT3, - * .bus_num = 1, - * .chip_select = 1, - * .platform_data = &max3107_pdata, - * }, - * }; - */ - -#define MAX310X_MAX_UARTS 4 - -/* MAX310X platform data structure */ -struct max310x_pdata { - /* Flags global to UART port */ - const u8 uart_flags[MAX310X_MAX_UARTS]; -#define MAX310X_ECHO_SUPRESS (0x00000002) /* Enable echo supress */ -#define MAX310X_AUTO_DIR_CTRL (0x00000004) /* Enable Auto direction - * control (RS-485) - */ -}; - -#endif -- cgit v1.3.1 From c957dd494615ccdb36d4892ef9bfd2287502fbfd Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 17 Feb 2014 15:19:18 +0530 Subject: tty: tty_ldisc.h: Remove duplicate include linux/wait.h was included twice. Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman --- include/linux/tty_ldisc.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index b8347c207cb8..add26da2faeb 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -126,7 +126,6 @@ #include #include -#include /* -- cgit v1.3.1 From 5811712ffbf593d98b6cc56461df5be4e9580245 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 20 Feb 2014 10:15:52 -0800 Subject: tty: serial: bcm63xx_uart: define UART_REG_SIZE constant The bcm63xx_uart driver uses RSET_UART_SIZE which is a constant defined for MIPS-based BCM63xx platforms, pull this constant value from the MIPS-specific header and put it in include/linux/serial_bcm63xx.h to make the driver platform agnostic. Signed-off-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 4 ++-- include/linux/serial_bcm63xx.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index d71143e4e9df..37e7e336f70a 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -589,7 +589,7 @@ static int bcm_uart_request_port(struct uart_port *port) { unsigned int size; - size = RSET_UART_SIZE; + size = UART_REG_SIZE; if (!request_mem_region(port->mapbase, size, "bcm63xx")) { dev_err(port->dev, "Memory region busy\n"); return -EBUSY; @@ -609,7 +609,7 @@ static int bcm_uart_request_port(struct uart_port *port) */ static void bcm_uart_release_port(struct uart_port *port) { - release_mem_region(port->mapbase, RSET_UART_SIZE); + release_mem_region(port->mapbase, UART_REG_SIZE); iounmap(port->membase); } diff --git a/include/linux/serial_bcm63xx.h b/include/linux/serial_bcm63xx.h index 570e964dc899..a80aa1a5bee2 100644 --- a/include/linux/serial_bcm63xx.h +++ b/include/linux/serial_bcm63xx.h @@ -116,4 +116,6 @@ UART_FIFO_PARERR_MASK | \ UART_FIFO_BRKDET_MASK) +#define UART_REG_SIZE 24 + #endif /* _LINUX_SERIAL_BCM63XX_H */ -- cgit v1.3.1 From a9c3f68f3cd8d55f809fbdb0c138ed061ea1bd25 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 22 Feb 2014 07:31:21 -0500 Subject: tty: Fix low_latency BUG The user-settable knob, low_latency, has been the source of several BUG reports which stem from flush_to_ldisc() running in interrupt context. Since 3.12, which added several sleeping locks (termios_rwsem and buf->lock) to the input processing path, the frequency of these BUG reports has increased. Note that changes in 3.12 did not introduce this regression; sleeping locks were first added to the input processing path with the removal of the BKL from N_TTY in commit a88a69c91256418c5907c2f1f8a0ec0a36f9e6cc, 'n_tty: Fix loss of echoed characters and remove bkl from n_tty' and later in commit 38db89799bdf11625a831c5af33938dcb11908b6, 'tty: throttling race fix'. Since those changes, executing flush_to_ldisc() in interrupt_context (ie, low_latency set), is unsafe. However, since most devices do not validate if the low_latency setting is appropriate for the context (process or interrupt) in which they receive data, some reports are due to misconfiguration. Further, serial dma devices for which dma fails, resort to interrupt receiving as a backup without resetting low_latency. Historically, low_latency was used to force wake-up the reading process rather than wait for the next scheduler tick. The effect was to trim multiple milliseconds of latency from when the process would receive new data. Recent tests [1] have shown that the reading process now receives data with only 10's of microseconds latency without low_latency set. Remove the low_latency rx steering from tty_flip_buffer_push(); however, leave the knob as an optional hint to drivers that can tune their rx fifos and such like. Cleanup stale code comments regarding low_latency. [1] https://lkml.org/lkml/2014/2/20/434 "Yay.. thats an annoying historical pain in the butt gone." -- Alan Cox Reported-by: Beat Bolli Reported-by: Pavel Roskin Acked-by: David Sterba Cc: Grant Edwards Cc: Stanislaw Gruszka Cc: Hal Murray Cc: # 3.12.x+ Signed-off-by: Peter Hurley Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ipwireless/tty.c | 3 --- drivers/tty/tty_buffer.c | 20 ++++---------------- drivers/usb/gadget/u_serial.c | 4 ++-- include/linux/tty.h | 2 +- 4 files changed, 7 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index ebd5bff0f5c1..17ee3bf0926b 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -176,9 +176,6 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, ": %d chars not inserted to flip buffer!\n", length - work); - /* - * This may sleep if ->low_latency is set - */ if (work) tty_flip_buffer_push(&tty->port); } diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 765125dff20e..8ebd9f88a6f6 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -351,14 +351,11 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); * Takes any pending buffers and transfers their ownership to the * ldisc side of the queue. It then schedules those characters for * processing by the line discipline. - * Note that this function can only be used when the low_latency flag - * is unset. Otherwise the workqueue won't be flushed. */ void tty_schedule_flip(struct tty_port *port) { struct tty_bufhead *buf = &port->buf; - WARN_ON(port->low_latency); buf->tail->commit = buf->tail->used; schedule_work(&buf->work); @@ -482,17 +479,15 @@ static void flush_to_ldisc(struct work_struct *work) */ void tty_flush_to_ldisc(struct tty_struct *tty) { - if (!tty->port->low_latency) - flush_work(&tty->port->buf.work); + flush_work(&tty->port->buf.work); } /** * tty_flip_buffer_push - terminal * @port: tty port to push * - * Queue a push of the terminal flip buffers to the line discipline. This - * function must not be called from IRQ context if port->low_latency is - * set. + * Queue a push of the terminal flip buffers to the line discipline. + * Can be called from IRQ/atomic context. * * In the event of the queue being busy for flipping the work will be * held off and retried later. @@ -500,14 +495,7 @@ void tty_flush_to_ldisc(struct tty_struct *tty) void tty_flip_buffer_push(struct tty_port *port) { - struct tty_bufhead *buf = &port->buf; - - buf->tail->commit = buf->tail->used; - - if (port->low_latency) - flush_to_ldisc(&buf->work); - else - schedule_work(&buf->work); + tty_schedule_flip(port); } EXPORT_SYMBOL(tty_flip_buffer_push); diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index b369292d4b90..ad0aca812002 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -549,8 +549,8 @@ static void gs_rx_push(unsigned long _port) port->read_started--; } - /* Push from tty to ldisc; without low_latency set this is handled by - * a workqueue, so we won't get callbacks and can hold port_lock + /* Push from tty to ldisc; this is handled by a workqueue, + * so we won't get callbacks and can hold port_lock */ if (do_push) tty_flip_buffer_push(&port->port); diff --git a/include/linux/tty.h b/include/linux/tty.h index 90b4fdc8a61f..b90b5c221ff0 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -208,7 +208,7 @@ struct tty_port { wait_queue_head_t delta_msr_wait; /* Modem status change */ unsigned long flags; /* TTY flags ASY_*/ unsigned char console:1, /* port is a console */ - low_latency:1; /* direct buffer flush */ + low_latency:1; /* optional: tune for latency */ struct mutex mutex; /* Locking */ struct mutex buf_mutex; /* Buffer alloc lock */ unsigned char *xmit_buf; /* Optional buffer */ -- cgit v1.3.1 From 45af780a0fcac8fbba0ac740a671b2af80bcf189 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 22 Feb 2014 16:01:35 +0400 Subject: serial: imx: Remove init() and exit() platform callbacks Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-imx/mach-mx31moboard.c | 21 +++++---------------- drivers/tty/serial/imx.c | 27 ++------------------------- include/linux/platform_data/serial-imx.h | 2 -- 3 files changed, 7 insertions(+), 43 deletions(-) (limited to 'include') diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index b3738e616f19..8f45afe785f8 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -128,27 +128,15 @@ static struct platform_device mx31moboard_flash = { .num_resources = 1, }; -static int moboard_uart0_init(struct platform_device *pdev) +static void __init moboard_uart0_init(void) { - int ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack"); - if (ret) - return ret; - - ret = gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0); - if (ret) + if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack")) { + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0); gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1)); - - return ret; -} - -static void moboard_uart0_exit(struct platform_device *pdev) -{ - gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1)); + } } static const struct imxuart_platform_data uart0_pdata __initconst = { - .init = moboard_uart0_init, - .exit = moboard_uart0_exit, }; static const struct imxuart_platform_data uart4_pdata __initconst = { @@ -543,6 +531,7 @@ static void __init mx31moboard_init(void) imx31_add_imx2_wdt(); + moboard_uart0_init(); imx31_add_imx_uart0(&uart0_pdata); imx31_add_imx_uart4(&uart4_pdata); diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 37c39390efb7..3b6c1a2e25de 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1901,7 +1901,6 @@ static void serial_imx_probe_pdata(struct imx_port *sport, static int serial_imx_probe(struct platform_device *pdev) { struct imx_port *sport; - struct imxuart_platform_data *pdata; void __iomem *base; int ret = 0; struct resource *res; @@ -1955,38 +1954,16 @@ static int serial_imx_probe(struct platform_device *pdev) imx_ports[sport->port.line] = sport; - pdata = dev_get_platdata(&pdev->dev); - if (pdata && pdata->init) { - ret = pdata->init(pdev); - if (ret) - return ret; - } - - ret = uart_add_one_port(&imx_reg, &sport->port); - if (ret) - goto deinit; platform_set_drvdata(pdev, sport); - return 0; -deinit: - if (pdata && pdata->exit) - pdata->exit(pdev); - return ret; + return uart_add_one_port(&imx_reg, &sport->port); } static int serial_imx_remove(struct platform_device *pdev) { - struct imxuart_platform_data *pdata; struct imx_port *sport = platform_get_drvdata(pdev); - pdata = dev_get_platdata(&pdev->dev); - - uart_remove_one_port(&imx_reg, &sport->port); - - if (pdata && pdata->exit) - pdata->exit(pdev); - - return 0; + return uart_remove_one_port(&imx_reg, &sport->port); } static struct platform_driver serial_imx_driver = { diff --git a/include/linux/platform_data/serial-imx.h b/include/linux/platform_data/serial-imx.h index 4adec9b154dd..3cc2e3c40914 100644 --- a/include/linux/platform_data/serial-imx.h +++ b/include/linux/platform_data/serial-imx.h @@ -23,8 +23,6 @@ #define IMXUART_IRDA (1<<1) struct imxuart_platform_data { - int (*init)(struct platform_device *pdev); - void (*exit)(struct platform_device *pdev); unsigned int flags; void (*irda_enable)(int enable); unsigned int irda_inv_rx:1; -- cgit v1.3.1 From 26de4f1b2fb45e53a9e8f4f913b9cdf6c294070b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 11 Mar 2014 11:11:19 +0100 Subject: serial: sh-sci: Add more register documentation Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Acked-by: Laurent Pinchart Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 28 +++++++------- include/linux/serial_sci.h | 93 ++++++++++++++++++++++++++++----------------- 2 files changed, 73 insertions(+), 48 deletions(-) (limited to 'include') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index c93154f690a6..22a508a638b9 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -911,7 +911,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) /* Disable future Rx interrupts */ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { disable_irq_nosync(irq); - scr |= 0x4000; + scr |= SCSCR_RDRQE; } else { scr &= ~SCSCR_RIE; } @@ -1200,7 +1200,9 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) */ reg = sci_getreg(port, SCFCR); if (reg->size) - serial_port_out(port, SCFCR, serial_port_in(port, SCFCR) | 1); + serial_port_out(port, SCFCR, + serial_port_in(port, SCFCR) | + SCFCR_LOOP); } } @@ -1496,9 +1498,9 @@ static void sci_start_tx(struct uart_port *port) if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { u16 new, scr = serial_port_in(port, SCSCR); if (s->chan_tx) - new = scr | 0x8000; + new = scr | SCSCR_TDRQE; else - new = scr & ~0x8000; + new = scr & ~SCSCR_TDRQE; if (new != scr) serial_port_out(port, SCSCR, new); } @@ -1525,7 +1527,7 @@ static void sci_stop_tx(struct uart_port *port) ctrl = serial_port_in(port, SCSCR); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) - ctrl &= ~0x8000; + ctrl &= ~SCSCR_TDRQE; ctrl &= ~SCSCR_TIE; @@ -1539,7 +1541,7 @@ static void sci_start_rx(struct uart_port *port) ctrl = serial_port_in(port, SCSCR) | port_rx_irq_mask(port); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) - ctrl &= ~0x4000; + ctrl &= ~SCSCR_RDRQE; serial_port_out(port, SCSCR, ctrl); } @@ -1551,7 +1553,7 @@ static void sci_stop_rx(struct uart_port *port) ctrl = serial_port_in(port, SCSCR); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) - ctrl &= ~0x4000; + ctrl &= ~SCSCR_RDRQE; ctrl &= ~port_rx_irq_mask(port); @@ -1614,7 +1616,7 @@ static void rx_timer_fn(unsigned long arg) u16 scr = serial_port_in(port, SCSCR); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { - scr &= ~0x4000; + scr &= ~SCSCR_RDRQE; enable_irq(s->irqs[SCIx_RXI_IRQ]); } serial_port_out(port, SCSCR, scr | SCSCR_RIE); @@ -1871,13 +1873,13 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, smr_val = serial_port_in(port, SCSMR) & 3; if ((termios->c_cflag & CSIZE) == CS7) - smr_val |= 0x40; + smr_val |= SCSMR_CHR; if (termios->c_cflag & PARENB) - smr_val |= 0x20; + smr_val |= SCSMR_PE; if (termios->c_cflag & PARODD) - smr_val |= 0x30; + smr_val |= SCSMR_PE | SCSMR_ODD; if (termios->c_cflag & CSTOPB) - smr_val |= 0x08; + smr_val |= SCSMR_STOP; uart_update_timeout(port, termios->c_cflag, baud); @@ -1885,7 +1887,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { - serial_port_out(port, SCSMR, (smr_val & ~3) | cks); + serial_port_out(port, SCSMR, (smr_val & ~SCSMR_CKS) | cks); serial_port_out(port, SCBRR, t); reg = sci_getreg(port, HSSRR); if (reg->size) diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 22b3640c9424..6c5e3bb282b0 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -10,45 +10,59 @@ #define SCIx_NOT_SUPPORTED (-1) -#define SCSCR_TIE (1 << 7) -#define SCSCR_RIE (1 << 6) -#define SCSCR_TE (1 << 5) -#define SCSCR_RE (1 << 4) -#define SCSCR_REIE (1 << 3) /* not supported by all parts */ -#define SCSCR_TOIE (1 << 2) /* not supported by all parts */ -#define SCSCR_CKE1 (1 << 1) -#define SCSCR_CKE0 (1 << 0) - -/* SCxSR SCI */ -#define SCI_TDRE 0x80 -#define SCI_RDRF 0x40 -#define SCI_ORER 0x20 -#define SCI_FER 0x10 -#define SCI_PER 0x08 -#define SCI_TEND 0x04 +/* SCSMR (Serial Mode Register) */ +#define SCSMR_CHR (1 << 6) /* 7-bit Character Length */ +#define SCSMR_PE (1 << 5) /* Parity Enable */ +#define SCSMR_ODD (1 << 4) /* Odd Parity */ +#define SCSMR_STOP (1 << 3) /* Stop Bit Length */ +#define SCSMR_CKS 0x0003 /* Clock Select */ + +/* Serial Control Register (@ = not supported by all parts) */ +#define SCSCR_TIE (1 << 7) /* Transmit Interrupt Enable */ +#define SCSCR_RIE (1 << 6) /* Receive Interrupt Enable */ +#define SCSCR_TE (1 << 5) /* Transmit Enable */ +#define SCSCR_RE (1 << 4) /* Receive Enable */ +#define SCSCR_REIE (1 << 3) /* Receive Error Interrupt Enable @ */ +#define SCSCR_TOIE (1 << 2) /* Timeout Interrupt Enable @ */ +#define SCSCR_CKE1 (1 << 1) /* Clock Enable 1 */ +#define SCSCR_CKE0 (1 << 0) /* Clock Enable 0 */ +/* SCIFA/SCIFB only */ +#define SCSCR_TDRQE (1 << 15) /* Tx Data Transfer Request Enable */ +#define SCSCR_RDRQE (1 << 14) /* Rx Data Transfer Request Enable */ + +/* SCxSR (Serial Status Register) on SCI */ +#define SCI_TDRE 0x80 /* Transmit Data Register Empty */ +#define SCI_RDRF 0x40 /* Receive Data Register Full */ +#define SCI_ORER 0x20 /* Overrun Error */ +#define SCI_FER 0x10 /* Framing Error */ +#define SCI_PER 0x08 /* Parity Error */ +#define SCI_TEND 0x04 /* Transmit End */ #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF, HSCIF */ -#define SCIF_ER 0x0080 -#define SCIF_TEND 0x0040 -#define SCIF_TDFE 0x0020 -#define SCIF_BRK 0x0010 -#define SCIF_FER 0x0008 -#define SCIF_PER 0x0004 -#define SCIF_RDF 0x0002 -#define SCIF_DR 0x0001 +/* SCxSR (Serial Status Register) on SCIF, HSCIF */ +#define SCIF_ER 0x0080 /* Receive Error */ +#define SCIF_TEND 0x0040 /* Transmission End */ +#define SCIF_TDFE 0x0020 /* Transmit FIFO Data Empty */ +#define SCIF_BRK 0x0010 /* Break Detect */ +#define SCIF_FER 0x0008 /* Framing Error */ +#define SCIF_PER 0x0004 /* Parity Error */ +#define SCIF_RDF 0x0002 /* Receive FIFO Data Full */ +#define SCIF_DR 0x0001 /* Receive Data Ready */ #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK) -/* SCSPTR, optional */ -#define SCSPTR_RTSIO (1 << 7) -#define SCSPTR_CTSIO (1 << 5) -#define SCSPTR_SPB2IO (1 << 1) -#define SCSPTR_SPB2DT (1 << 0) +/* SCFCR (FIFO Control Register) */ +#define SCFCR_LOOP (1 << 0) /* Loopback Test */ + +/* SCSPTR (Serial Port Register), optional */ +#define SCSPTR_RTSIO (1 << 7) /* Serial Port RTS Pin Input/Output */ +#define SCSPTR_CTSIO (1 << 5) /* Serial Port CTS Pin Input/Output */ +#define SCSPTR_SPB2IO (1 << 1) /* Serial Port Break Input/Output */ +#define SCSPTR_SPB2DT (1 << 0) /* Serial Port Break Data */ /* HSSRR HSCIF */ -#define HSCIF_SRE 0x8000 +#define HSCIF_SRE 0x8000 /* Sampling Rate Register Enable */ enum { SCIx_PROBE_REGTYPE, @@ -73,10 +87,19 @@ enum { * Not all registers will exist on all parts. */ enum { - SCSMR, SCBRR, SCSCR, SCxSR, - SCFCR, SCFDR, SCxTDR, SCxRDR, - SCLSR, SCTFDR, SCRFDR, SCSPTR, - HSSRR, + SCSMR, /* Serial Mode Register */ + SCBRR, /* Bit Rate Register */ + SCSCR, /* Serial Control Register */ + SCxSR, /* Serial Status Register */ + SCFCR, /* FIFO Control Register */ + SCFDR, /* FIFO Data Count Register */ + SCxTDR, /* Transmit (FIFO) Data Register */ + SCxRDR, /* Receive (FIFO) Data Register */ + SCLSR, /* Line Status Register */ + SCTFDR, /* Transmit FIFO Data Count Register */ + SCRFDR, /* Receive FIFO Data Count Register */ + SCSPTR, /* Serial Port Register */ + HSSRR, /* Sampling Rate Register */ SCIx_NR_REGS, }; -- cgit v1.3.1